poj3678(给定异或组求是否存在能够组成满足条件的ai)
题:http://poj.org/problem?id=3678
题意:给定m组i和j的AND,OR,XOR组运算,判断是否存在序列满足条件
分析:注意范围0<=ci<=1,0<=ai<=1;
将i设为0,i‘设为1,分类讨论建立2-SAT模型即可
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<math.h> using namespace std; #define pb push_back const int M=2e3+3; int n,m; vector<int>g[M],rg[M],cb; int vis[M],cmp[M]; char s[10]; void py(){ puts("YES"); } void pn(){ puts("NO"); } void init(){ for(int i=0;i<=2*n;i++) g[i].clear(),rg[i].clear(),cmp[i]=0,vis[i]=0; cb.clear(); } void addedge(int u,int v){ g[u].pb(v); rg[v].pb(u); } void dfs(int u){ vis[u]=1; for(int i=0;i<(int)g[u].size();i++)if(!vis[g[u][i]]) dfs(g[u][i]); cb.pb(u); } void rdfs(int u,int k){ vis[u]=1; cmp[u]=k; for(int i=0;i<(int)rg[u].size();i++)if(!vis[rg[u][i]]) rdfs(rg[u][i],k); } bool scc(){ for(int i=0;i<2*n;i++) if(!vis[i]) dfs(i); memset(vis,0,sizeof(vis)); int k=0; for(int i=(int)cb.size()-1;i>=0;i--) if(!vis[i]) rdfs(cb[i],++k); for(int i=0;i<2*n;i+=2) if(cmp[i]==cmp[i+1])return false; return true; } int main(){ while(scanf("%d%d",&n,&m)!=EOF){ init(); while(m--){ int x,y,c; scanf("%d%d%d%s",&x,&y,&c,s); if(s[0]=='A'){ if(c==1){///同时取1 addedge(2*x,2*x+1); addedge(2*y,2*y+1); } else{///不同时取1 addedge(2*x+1,2*y); addedge(2*y+1,2*x); } } else if(s[0]=='O'){ if(c==0){///同时取0 addedge(2*x+1,2*x); addedge(2*y+1,2*y); } else{///不同时取0 addedge(2*x,2*y+1); addedge(2*y,2*x+1); } } else{ if(c==0){///要相同 addedge(2*x,2*y); addedge(2*y,2*x); addedge(2*x+1,2*y+1); addedge(2*y+1,2*x+1); } else{///要不同 addedge(2*x,2*y+1); addedge(2*y+1,2*x); addedge(2*y,2*x+1); addedge(2*x+1,2*y); } } } if(scc()) py(); else pn(); } return 0; }