标签:
题意:每个数只有0,1两种可能,给出两两之间的AND,OR,XOR的值,判断有没有解
裸题。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int N = 2010; struct Edge { int v,next; }es[N*N]; int head[N]; int n,m; int tmp[N],low[N],dfn[N],sta[N],top,scc,index; int cnt; inline void add_edge(int u,int v) { es[cnt].v=v; es[cnt].next=head[u]; head[u]=cnt++; } void tarjan(int u) { low[u]=dfn[u]=++index; sta[++top]=u; tmp[u]=1; for(int i=head[u];~i;i=es[i].next) { int v=es[i].v; if(!tmp[v]) tarjan(v); if(tmp[v]==1) low[u]=min(low[u],low[v]); } if(low[u]==dfn[u]) { scc++; do { int v=sta[top]; tmp[v]=2; low[v]=scc; }while(sta[top--]!=u); } } bool judge() { for(int i=0;i<2*n;i++) if(low[i]==low[i^1]) return false; return true; } void ini() { memset(head,-1,sizeof(head)); memset(tmp,0,sizeof(tmp)); top=scc=index=cnt=0; } int main() { while(~scanf("%d%d",&n,&m)) { ini(); for(int i=1;i<=m;i++) { int u,v,c; char op[10]; scanf("%d%d%d%s",&u,&v,&c,op); u<<=1,v<<=1; if(op[0]=='A') { if(c==1)add_edge(u,u^1),add_edge(v,v^1); else add_edge(u^1,v),add_edge(v^1,u); } else if(op[0]=='O') { if(c) add_edge(u,v^1),add_edge(v,u^1); else add_edge(u^1,u),add_edge(v^1,v); } else { if(c) add_edge(u,v^1),add_edge(v,u^1),add_edge(u^1,v),add_edge(v^1,u); else add_edge(u,v),add_edge(v,u),add_edge(u^1,v^1),add_edge(v^1,u^1); } } for(int i=0;i<2*n;i++) if(!tmp[i]) tarjan(i); if(judge()) puts("YES"); else puts("NO"); } return 0; }
POJ 3678 Katu Puzzle (2-sat基础)
标签:
原文地址:http://blog.csdn.net/kalilili/article/details/45693727