URAL 1382 Game with Cards 解题报告
来源:互联网 发布:仿美团外卖小程序源码 编辑:程序博客网 时间:2024/04/25 12:30
题目
比赛
题意:
有N张牌,N个人,每个人会说两句话,"我拿着牌a"和"b拿着牌c",这两句话中有且只有一句话是对的。
求每个人说的话中哪一句话是对的,题目保证一定有解
思路:
2-sat,对于第i个人,有第一句是对的I1,第二句话是对的I2两种互斥的状态,可以把I1看成"i拿着牌a",则当两句话中人相同牌不同时,或者人不同牌相同时,这两句话产生冲突,然后就套用2-sat输出解的模板。
代码:
#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <queue>using namespace std;#define maxN 1005#define maxn 2005#define maxm 5000005int n;struct node{ int s,t; int next;}e[maxm],e2[maxm];int ecnt,ecnt2,pre[maxn],pre2[maxn];int a[maxn],b[maxn];void addEdge(int u,int v){ e[ecnt].s=u; e[ecnt].t=v; e[ecnt].next=pre[u]; pre[u]=ecnt++;}void addE(int u,int v){ e2[ecnt2].s=u; e2[ecnt2].t=v; e2[ecnt2].next=pre2[u]; pre2[u]=ecnt2++;}int Dindex,top,cnt;int dfn[maxn],low[maxn],bel[maxn];int stack[maxn];bool instack[maxn];void tarjan(int u){ int v; dfn[u]=low[u]=++Dindex; stack[++top]=u; instack[u]=true; for (int i=pre[u];i!=-1;i=e[i].next) { v=e[i].t; if (!dfn[v]) { tarjan(v); if (low[v]<low[u]) low[u]=low[v]; } else if (instack[v]&&dfn[v]<low[u]) low[u]=dfn[v]; } if (dfn[u]==low[u]) { cnt++; do { v=stack[top--]; instack[v]=false; bel[v]=cnt; }while (u!=v); }}void solve(){ Dindex=top=cnt=0; for (int i=1;i<=2*n;i++) if (!dfn[i]) tarjan(i);}int cf[maxn],in[maxn],col[maxn];bool ans[maxn];void re_build(){ ecnt2=0; memset(pre2,-1,sizeof(pre2)); for (int i=0;i<ecnt;i++) { if (bel[e[i].s]!=bel[e[i].t]) { addE(bel[e[i].t],bel[e[i].s]); in[bel[e[i].s]]++; } }}void topsort(){ queue<int> q; for (int i=1;i<=cnt;i++) if (in[i]==0) q.push(i); while (!q.empty()) { int u=q.front(); q.pop(); if (col[u]==0) { col[u]=1; col[cf[u]]=-1; } for (int i=pre2[u];i!=-1;i=e2[i].next) { int v=e2[i].t; in[v]--; if (in[v]==0) q.push(v); } }}void make(){ solve(); for (int i=1;i<=n;i++) { cf[bel[i]]=bel[i+n]; cf[bel[i+n]]=bel[i]; } re_build(); topsort(); for (int i=1;i<n;i++) if (col[bel[i]]==1) printf("1 "); else printf("2 "); if (col[bel[n]]==1) printf("1\n"); else printf("2\n");}int main(){ //freopen("/home/moor/Code/input.txt","r",stdin); scanf("%d",&n); int x,y,z; for (int i=1;i<=n;i++) { scanf("%d%d%d",&x,&y,&z); a[i]=i; b[i]=x; a[i+n]=y; b[i+n]=z; } ecnt=0; memset(pre,-1,sizeof(pre)); for (int i=1;i<=2*n;i++) for (int j=i+1;j<=2*n;j++) { if ((a[i]==a[j]&&b[i]!=b[j])||(a[i]!=a[j]&&b[i]==b[j])) { if (j<=n) addEdge(i,j+n); else addEdge(i,j-n); if (i<=n) addEdge(j,i+n); else addEdge(j,i-n); } } make(); return 0;}
- URAL 1382 Game with Cards 解题报告
- URAL 1382 Game with Cards
- URAL 1382 Game with Cards (2-SAT)
- [解题报告]Ural 1011 Conductors
- URAL 1389 Roadworks 解题报告
- URAL 1386 Maze 解题报告
- 1225. Flags URAL 解题报告
- 1119. Metro 解题报告 URAL
- URAL 1017. Staircases 解题报告
- URAL 1936 Roshambo 解题报告
- Ural 1020 Rope 解题报告
- Dungeon Game解题报告
- USACO A Game解题报告
- USACO A Game 解题报告
- poj1753 Flip Game 解题报告
- HDU 4616 Game 解题报告
- Leetcode Jump Game 解题报告
- USACO Letter Game 解题报告
- IBOutlet IBaction 详解
- 观察者模式的简单实现
- 钩子函数的学习
- C,C++网络编程学习指南
- centos 中文乱码
- URAL 1382 Game with Cards 解题报告
- java连接oracle数据库
- javac编译后的.class文件都是unicode
- task
- nyist-673
- 杭电 2563 统计问题
- 为什么要进行傅立叶变换?如何用Matlab实现快速傅立叶变换?
- linux升级gcc
- 【新闻§Windows体验指数疑似在Win8.1中被移除§】