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"
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 const int MAXN = 2010; 6 const int MAXM = 1000010*4; 7 8 struct TwoSAT{ 9 int n, ecnt, dfs_clock, scc_cnt; 10 int St[MAXN], c; 11 int head[MAXN], sccno[MAXN], lowlink[MAXN], pre[MAXN]; 12 int next[MAXM], to[MAXM]; 13 14 void init(int nn){ 15 n = nn; 16 ecnt = 2; dfs_clock = scc_cnt = 0; 17 memset(head,0,sizeof(head)); 18 } 19 20 void addEdge(int x, int y){ 21 to[ecnt] = y; next[ecnt] = head[x]; head[x] = ecnt++; 22 } 23 24 void addEdge2(int x, int y){ 25 addEdge(x,y); addEdge(y,x); 26 } 27 28 void dfs(int u){ 29 lowlink[u] = pre[u] = ++dfs_clock; 30 St[++c] = u; 31 for(int p = head[u]; p; p = next[p]){ 32 int &v = to[p]; 33 if(!pre[v]){ 34 dfs(v); 35 if(lowlink[u] > lowlink[v]) lowlink[u] = lowlink[v]; 36 }else if(!sccno[v]){ 37 if(lowlink[u] > pre[v]) lowlink[u] = pre[v]; 38 } 39 } 40 if(lowlink[u] == pre[u]){ 41 ++scc_cnt; 42 while(true){ 43 int x = St[c--]; 44 sccno[x] = scc_cnt; 45 if(x == u) break; 46 } 47 } 48 } 49 50 bool solve(){ 51 for(int i = 0; i < n; ++i) 52 if(!pre[i]) dfs(i); 53 for(int i = 0; i < n; i += 2) 54 if(sccno[i] == sccno[i^1]) return false; 55 return true; 56 } 57 58 } G; 59 60 int main(){ 61 int n, m, a, b, c; 62 char d[5]; 63 while(scanf("%d%d",&n,&m)!=EOF){ 64 G.init(2*n); 65 while(m--){ 66 scanf("%d%d%d%s",&a,&b,&c,d); 67 if(d[0] == 'A' && c == 0){//a&b=false 68 G.addEdge(a*2, b*2+1); 69 G.addEdge(b*2, a*2+1); 70 } 71 if(d[0] == 'A' && c == 1){//a&b=true 72 G.addEdge(a*2+1, a*2); 73 G.addEdge(b*2+1, b*2); 74 } 75 if(d[0] == 'O' && c == 0){//a|b=false 76 G.addEdge(a*2, a*2+1); 77 G.addEdge(b*2, b*2+1); 78 } 79 if(d[0] == 'O' && c == 1){//a|b=true 80 G.addEdge(b*2+1, a*2); 81 G.addEdge(a*2+1, b*2); 82 } 83 if(d[0] == 'X' && c == 0){//a^b=false 84 G.addEdge2(a*2, b*2); 85 G.addEdge2(a*2+1, b*2+1); 86 } 87 if(d[0] == 'X' && c == 1){//a^b=true 88 G.addEdge2(a*2, b*2+1); 89 G.addEdge2(a*2+1, b*2); 90 } 91 } 92 if(G.solve()) printf("YES\n"); 93 else printf("NO\n"); 94 } 95 return 0; 96 }