POJ3678 KATU PUZZLE
POJ 3678 KATU PUZZLE
题目大意:
给定N个点M条边的无向图,每条边的有一个对应的运算符(AND,OR,XOR之一)和一个对应的值(0或1),问是否可以给每个点安排对应的值使得每条边的两个端点的值按照边上的运算符计算得到对应边上的值?
1 ≤ N ≤ 1000,0 ≤ M ≤ 1,000,000
——————————————————————————————————
比较好的2-SAT题目,可以很好的练习建图!
a&b=1:~a->a,~b->b
a&b=0:a->~b,b->~a
a|b=1:~a->b,~b->a
a|b=0:a->~a,b->~b
a^b=0:a->b,b->a,~a->~b,~b->~a
a^b=1:a->~b,~b->a,~a->b,b->~a
只里面要注意,a&b=1和a|b=0不存在推导的关系,关系是一定的。所以这样写!!
——————————————————————————————————
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 const int maxn=1010; 7 const int maxm=1e6+10; 8 int n,m; 9 char s[5]; 10 struct edge 11 { 12 int u,v,nxt; 13 }e[maxm*4]; 14 int head[maxn<<1],js; 15 void addage(int u,int v) 16 { 17 e[++js].u=u;e[js].v=v; 18 e[js].nxt=head[u];head[u]=js; 19 } 20 int dfn[maxn<<1],low[maxn<<1],cnt,st[maxn<<1],top,lt[maxn<<1],lts; 21 void tarjan(int u) 22 { 23 dfn[u]=low[u]=++cnt; 24 st[++top]=u; 25 for(int i=head[u];i;i=e[i].nxt) 26 { 27 int v=e[i].v; 28 if(!dfn[v]) 29 { 30 tarjan(v); 31 low[u]=min(low[u],low[v]); 32 } 33 else if(!lt[v]) low[u]=min(low[u],dfn[v]); 34 } 35 if(dfn[u]==low[u]) 36 { 37 lt[u]=++lts; 38 while(st[top]!=u)lt[st[top--]]=lts; 39 --top; 40 } 41 } 42 void init() 43 { 44 memset(head,0,sizeof head); 45 js=0; 46 memset(dfn,0,sizeof dfn); 47 memset(low,0,sizeof low); 48 cnt=top=lts=0; 49 memset(lt,0,sizeof lt); 50 } 51 int main() 52 { 53 while(scanf("%d%d",&n,&m)==2) 54 { 55 init(); 56 for(int a,b,c,i=1;i<=m;++i) 57 { 58 scanf("%d%d%d%s",&a,&b,&c,s); 59 ++a;++b; 60 if(s[0]=='A') 61 { 62 if(c==1)addage(a*2,a*2-1),addage(b*2,b*2-1); 63 else if(c==0)addage(a*2-1,b*2),addage(b*2-1,a*2); 64 } 65 else if(s[0]=='O') 66 { 67 if(c==1)addage(a*2,b*2-1),addage(b*2,a*2-1); 68 else if(c==0)addage(a*2-1,a*2),addage(b*2-1,b*2); 69 } 70 else 71 { 72 if(c==0)addage(a*2-1,b*2-1),addage(b*2-1,a*2-1),addage(a*2,b*2),addage(b*2,a*2); 73 else if(c==1)addage(a*2-1,b*2),addage(b*2,a*2-1),addage(a*2,b*2-1),addage(b*2-1,a*2); 74 } 75 } 76 for(int i=1;i<=n*2;++i) 77 if(!dfn[i])tarjan(i); 78 for(int i=1;i<=n;++i) 79 if(lt[i*2]==lt[i*2-1]) 80 { 81 puts("NO"); 82 return 0; 83 } 84 puts("YES"); 85 } 86 return 0; 87 }