2-sat经典建图,注意AND为1的时候,a=0要和a=1连边,b同理,因为此时a,b都不能为0。
OR为0时候,a=1要和a=0连边,b同理,因为此时a,b都不能为1。
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorithm> #include<cmath> using namespace std; #define maxn 1005 vector<int> g[maxn*2]; bool mark[maxn*2]; int S[maxn*2],cnt,n,m; void init() { for(int i=0;i<n*2;i++) g[i].clear(); memset(mark,false,sizeof(mark)); } void add(int x,int xval,int y,int yval) { x=x*2+xval; y=y*2+yval; g[x].push_back(y); } bool dfs(int x) { if(mark[x^1]) return false; if(mark[x]) return true; mark[x]=true; S[cnt++]=x; for(int i=0;i<g[x].size();i++) if(!dfs(g[x][i])) return false; return true; } bool solve() { for(int i=0;i<n*2;i+=2) { if(!mark[i]&&!mark[i+1]) { cnt=0; if(!dfs(i)) { while(cnt>0) mark[S[--cnt]]=false; if(!dfs(i+1)) return false; } } } return true; } void debug(int k) { printf("%d:",k); for(int i=0;i<g[k].size();i++) { printf(" %d",g[k][i]); } puts(""); } int main() { int a,b,c; char str[6]; while(~scanf("%d%d",&n,&m)) { init(); for(int i=1;i<=m;i++) { scanf("%d%d%d%s",&a,&b,&c,str); if(str[0]=='A') { if(c) add(a,0,a,1), add(b,0,b,1); else add(a,1,b,0), add(b,1,a,0); } else if(str[0]=='O') { if(c) add(a,0,b,1), add(b,0,a,1); else add(a,1,a,0), add(b,1,b,0); } else if(str[0]=='X') { if(c) add(a,0,b,1), add(a,1,b,0), add(b,0,a,1), add(b,1,a,0); else add(a,1,b,1), add(a,0,b,0), add(b,0,a,0), add(b,1,a,1); } } printf("%s\n",solve()?"YES":"NO"); } return 0; } /* 3 3 0 1 1 XOR 1 2 1 XOR 2 0 1 XOR */
原文地址:http://blog.csdn.net/t1019256391/article/details/35221415