Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 9238 | Accepted: 3436 |
Description
Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a boolean operator op (one of AND, OR, XOR) and an integer c (0 ≤ c ≤ 1). One Katu is solvable if one can find each vertex Vi a value Xi (0 ≤ Xi ≤ 1) such that for each edge e(a, b) labeled by op and c, the following formula holds:
Xa op Xb = c
The calculating rules are:
|
|
|
Given a Katu Puzzle, your task is to determine whether it is solvable.
Input
The first line contains two integers N (1 ≤ N ≤ 1000) and M,(0 ≤ M ≤ 1,000,000) indicating the number of vertices and edges.
The following M lines contain three integers a (0 ≤ a < N), b(0 ≤ b < N), c and an operator op each, describing the edges.
Output
Output a line containing "YES" or "NO".
Sample Input
4 4 0 1 1 AND 1 2 1 OR 3 2 0 AND 3 0 0 XOR
Sample Output
YES
Hint
X0 = 1, X1 = 1, X2 = 0, X3 = 1.
Source
POJ Founder Monthly Contest – 2008.07.27, Dagger
只需要判断可行性,不用求值。
2-sat妥妥的。
模拟运算符模式连边,跑一边tarjan就行。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const int mxn=12000; 8 //bas 9 int n,m; 10 //edge 11 struct edge{ 12 int to; 13 int next; 14 }e[mxn*100]; 15 int hd[mxn],cnt=0; 16 void add_edge(int u,int v){ 17 e[++cnt].next=hd[u];e[cnt].to=v;hd[u]=cnt; 18 } 19 20 //tarjan 21 int vis[mxn]; 22 int dfn[mxn],low[mxn]; 23 int st[mxn],top; 24 bool inst[mxn]; 25 int dtime=0; 26 int belone[mxn],tot; 27 void tarjan(int s){ 28 low[s]=dfn[s]=++dtime; 29 st[++top]=s; 30 inst[s]=1; 31 for(int i=hd[s];i;i=e[i].next){ 32 int v=e[i].to; 33 if(!dfn[v]){ 34 tarjan(v); 35 low[s]=min(low[s],low[v]); 36 } 37 else if(inst[v]){ 38 low[s]=min(low[s],dfn[v]); 39 } 40 } 41 int v; 42 if(low[s]==dfn[s]){ 43 cnt++; 44 do{ 45 v=st[top--]; 46 inst[v]=0; 47 belone[v]=cnt; 48 49 }while(v!=s); 50 } 51 return; 52 } 53 void Build(int a,int b,int c,char op){ 54 switch(op){ 55 case ‘A‘:{ 56 if(c==1){ 57 add_edge(a+n,a);//原点表示选1, +n点表示0; 58 add_edge(b+n,b); 59 add_edge(a,b); 60 add_edge(b,a); 61 62 } 63 else{ 64 add_edge(a,b+n); 65 add_edge(b,a+n); 66 } 67 break; 68 } 69 case ‘O‘:{ 70 if(c==1){ 71 add_edge(a+n,b); 72 add_edge(b+n,a); 73 } 74 else{ 75 add_edge(a,a+n); 76 add_edge(b,b+n); 77 add_edge(a+n,b+n); 78 add_edge(b+n,a+n); 79 } 80 break; 81 } 82 case ‘X‘:{ 83 if(c==1){ 84 add_edge(a,b+n); 85 add_edge(b,a+n); 86 add_edge(a+n,b); 87 add_edge(b+n,a); 88 } 89 else{ 90 add_edge(a,b); 91 add_edge(b,a); 92 add_edge(b+n,a+n); 93 add_edge(a+n,b+n); 94 } 95 break; 96 } 97 98 } 99 } 100 int main(){ 101 scanf("%d%d",&n,&m); 102 int i,j; 103 int a,b,c; 104 char op[10]; 105 for(i=1;i<=m;i++){ 106 scanf("%d%d%d%s",&a,&b,&c,op); 107 a++;b++; 108 Build(a,b,c,op[0]); 109 } 110 for(i=1;i<=2*n;i++)if(!dfn[i])tarjan(i); 111 for(i=1;i<=n;i++){ 112 if(belone[i]==belone[i+n] && belone[i]!=0){ 113 printf("NO\n"); 114 return 0; 115 } 116 } 117 printf("YES\n"); 118 return 0; 119 }