Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 740 Accepted Submission(s): 301
题意:
有两个人玩一个石头剪刀布的游戏,两个人连续玩N轮,给出其中
一个人的N轮出的情况和该人对另外一个人的一些限制条件,有两种限制:
每种限制表示为:(a,b,c) ,如果c==0 则表示该人对另外一个人的限制为第a
局和第b局出的应该一样,如果c==1表示不一样,问另外一个人是否有赢的
可能。
2-SAT的题目一看就看出来了。两种选择,有的情况是矛盾的。
主要是建图,建图过程要细心,很容易出错的。
/* HDU 4115 题意: 有两个人玩一个石头剪刀布的游戏,两个人连续玩N轮,给出其中 一个人的N轮出的情况和该人对另外一个人的一些限制条件,有两种限制: 每种限制表示为:(a,b,c) ,如果c==0 则表示该人对另外一个人的限制为第a 局和第b局出的应该一样,如果c==1表示不一样,问另外一个人是否有赢的 可能。 */ #include<stdio.h> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<string.h> using namespace std; const int MAXN=22000;// bool visit[MAXN]; queue<int>q1,q2; //vector建图方法很妙 vector<vector<int> >adj; //原图 //中间一定要加空格把两个'>'隔开 vector<vector<int> >radj;//逆图 vector<vector<int> >dag;//缩点后的逆向DAG图 int n,m,cnt; int id[MAXN],order[MAXN],ind[MAXN];//强连通分量,访问顺序,入度 void dfs(int u) { visit[u]=true; int i,len=adj[u].size(); for(i=0;i<len;i++) if(!visit[adj[u][i]]) dfs(adj[u][i]); order[cnt++]=u; } void rdfs(int u) { visit[u]=true; id[u]=cnt; int i,len=radj[u].size(); for(i=0;i<len;i++) if(!visit[radj[u][i]]) rdfs(radj[u][i]); } void korasaju() { int i; memset(visit,false,sizeof(visit)); for(cnt=0,i=0;i<2*n;i++) if(!visit[i]) dfs(i); memset(id,0,sizeof(id)); memset(visit,false,sizeof(visit)); for(cnt=0,i=2*n-1;i>=0;i--) if(!visit[order[i]]) { cnt++;//这个一定要放前面来 rdfs(order[i]); } } bool solvable() { for(int i=0;i<n;i++) if(id[2*i]==id[2*i+1]) return false; return true; } void add(int x,int y) { adj[x].push_back(y); radj[y].push_back(x); } int a[MAXN],b[MAXN]; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T; int x,y,z; scanf("%d",&T); int iCase=0; while(T--) { iCase++; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { scanf("%d",&a[i]); if(a[i]==1)b[i]=2; else if(a[i]==2)b[i]=3; else b[i]=1; if(a[i]>b[i])swap(a[i],b[i]); } adj.assign(2*n,vector<int>()); radj.assign(2*n,vector<int>()); bool flag=true; while(m--) { scanf("%d%d%d",&x,&y,&z); x--; y--; if(!flag)continue; if(x==y) { if(z==1)flag=false; continue; } if(z==0)//要相等 { /* //这种加边方法也可以 if(a[x]==a[y]&&b[x]==b[y]) { adj[2*x].push_back(2*y); adj[2*y].push_back(2*x); adj[2*x+1].push_back(2*y+1); adj[2*y+1].push_back(2*x+1); radj[2*x].push_back(2*y); radj[2*y].push_back(2*x); radj[2*x+1].push_back(2*y+1); radj[2*y+1].push_back(2*x+1); } else if(a[x]==a[y]&&b[x]!=b[y])//只能选a { adj[2*x+1].push_back(2*x); adj[2*y+1].push_back(2*y); radj[2*x].push_back(2*x+1); radj[2*y].push_back(2*y+1); } else if(a[x]!=a[y]&&b[x]==b[y])//只能选b { adj[2*x].push_back(2*x+1); adj[2*y].push_back(2*y+1); radj[2*x+1].push_back(2*x); radj[2*y+1].push_back(2*y); } else if(a[x]==b[y])//23和12 { adj[2*x+1].push_back(2*x); adj[2*y].push_back(2*y+1); radj[2*x].push_back(2*x+1); radj[2*y+1].push_back(2*y); } else if(b[x]==a[y]) { adj[2*x].push_back(2*x+1); adj[2*y+1].push_back(2*y); radj[2*x+1].push_back(2*x); radj[2*y].push_back(2*y+1); } */ if(a[x]!=a[y]) { add(2*x,2*y+1); add(2*y,2*x+1); } if(a[x]!=b[y]) { add(2*x,2*y); add(2*y+1,2*x+1); } if(b[x]!=a[y]) { add(2*x+1,2*y+1); add(2*y,2*x); } if(b[x]!=b[y]) { add(2*x+1,2*y); add(2*y+1,2*x); } } else if(z==1) { /* //这种加边方法也可以 if(a[x]==a[y]&&b[x]==b[y]) { adj[2*x].push_back(2*y+1); adj[2*y].push_back(2*x+1); adj[2*x+1].push_back(2*y); adj[2*y+1].push_back(2*x); radj[2*x+1].push_back(2*y); radj[2*y+1].push_back(2*x); radj[2*x].push_back(2*y+1); radj[2*y].push_back(2*x+1); } else if(a[x]==a[y]&&b[x]!=b[y]) { adj[2*x].push_back(2*y+1); adj[2*y].push_back(2*x+1); radj[2*y+1].push_back(2*x); radj[2*x+1].push_back(2*y); } else if(a[x]!=a[y]&&b[x]==b[y]) { adj[2*x+1].push_back(2*y); adj[2*y+1].push_back(2*x); radj[2*y].push_back(2*x+1); radj[2*x].push_back(2*y+1); } else if(a[x]==b[y]) { adj[2*x].push_back(2*y); adj[2*y+1].push_back(2*x+1); radj[2*y].push_back(2*x); radj[2*x+1].push_back(2*y+1); } else if(b[x]==a[y]) { adj[2*x+1].push_back(2*y+1); adj[2*y].push_back(2*x); radj[2*y+1].push_back(2*x+1); radj[2*x].push_back(2*y); } */ if(a[x]==a[y]) { add(2*x,2*y+1); add(2*y,2*x+1); } if(a[x]==b[y]) { add(2*x,2*y); add(2*y+1,2*x+1); } if(b[x]==a[y]) { add(2*x+1,2*y+1); add(2*y,2*x); } if(b[x]==b[y]) { add(2*x+1,2*y); add(2*y+1,2*x); } } } if(!flag) { printf("Case #%d: no\n",iCase); continue; } korasaju(); if(solvable())printf("Case #%d: yes\n",iCase); else printf("Case #%d: no\n",iCase); } return 0; }