首页 > 代码库 > POJ 3678
POJ 3678
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 7391 | Accepted: 2717 |
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
Source
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <stack> 6 7 using namespace std; 8 9 const int MAX_N = 1005; 10 const int edge = 1e6 + 5; 11 int first[2 * MAX_N],Next[4 * edge],v[4 * edge]; 12 int N,M,dfs_clock,scc_cnt; 13 int low[2 * MAX_N],pre[2 * MAX_N],cmp[2 * MAX_N]; 14 stack<int > S; 15 16 void dfs(int u) { 17 low[u] = pre[u] = ++dfs_clock; 18 S.push(u); 19 for(int e = first[u]; e != -1; e = Next[e]) { 20 if(!pre[ v[e] ]) { 21 dfs(v[e]); 22 low[u] = min(low[u],low[ v[e] ]); 23 } else { 24 if(!cmp[ v[e] ]) { 25 low[u] = min(low[u],pre[ v[e] ]); 26 } 27 } 28 } 29 30 if(pre[u] == low[u]) { 31 ++scc_cnt; 32 for(;;) { 33 int x = S.top(); S.pop(); 34 cmp[x] = scc_cnt; 35 if(x == u) break; 36 } 37 } 38 } 39 40 void scc() { 41 dfs_clock = scc_cnt = 0; 42 memset(cmp,0,sizeof(cmp)); 43 memset(pre,0,sizeof(pre)); 44 45 for(int i = 0; i < 2 * N; ++i) if(!pre[i]) dfs(i); 46 } 47 48 void add_edge(int id,int u) { 49 int e = first[u]; 50 Next[id] = e; 51 first[u] = id; 52 } 53 54 bool solve() { 55 scc(); 56 for(int i = 0; i < N; ++i) { 57 if(cmp[i] == cmp[N + i]) return false; 58 } 59 return true; 60 } 61 62 void build(int a,int b,int c,char ch[],int &len) { 63 if(strcmp(ch,"AND") == 0) { 64 if(c == 0) { 65 v[len] = b; 66 add_edge(len++,a + N); 67 v[len] = a; 68 add_edge(len++,b + N); 69 } else { 70 v[len] = b + N; 71 add_edge(len++,a + N); 72 v[len] = a + N; 73 add_edge(len++,b + N); 74 v[len] = a + N; 75 add_edge(len++,a); 76 v[len] = b + N; 77 add_edge(len++,b); 78 } 79 } 80 if(strcmp(ch,"OR") == 0) { 81 if(c == 0) { 82 v[len] = b; 83 add_edge(len++,a); 84 v[len] = b; 85 add_edge(len++,b + N); 86 v[len] = a; 87 add_edge(len++,b); 88 v[len] = a; 89 add_edge(len++,a + N); 90 } else { 91 v[len] = b + N; 92 add_edge(len++,a); 93 v[len] = a + N; 94 add_edge(len++,b); 95 } 96 } 97 if(strcmp(ch,"XOR") == 0) { 98 if(c == 0) { 99 v[len] = b; 100 add_edge(len++,a); 101 v[len] = a + N; 102 add_edge(len++,b + N); 103 v[len] = a; 104 add_edge(len++,b); 105 v[len] = b + N; 106 add_edge(len++,a + N); 107 } else { 108 v[len] = b + N; 109 add_edge(len++,a); 110 v[len] = a + N; 111 add_edge(len++,b); 112 v[len] = b; 113 add_edge(len++,a + N); 114 v[len] = a; 115 add_edge(len++,b + N); 116 } 117 } 118 119 } 120 121 int main() 122 { 123 //freopen("sw.in","r",stdin); 124 scanf("%d%d",&N,&M); 125 for(int i = 0; i < 2 * N; ++i) first[i] = -1; 126 int len = 0; 127 for(int i = 1; i <= M; ++i) { 128 int a,b,c; 129 char ch[10]; 130 scanf("%d%d%d%s",&a,&b,&c,ch); 131 build(a,b,c,ch,len); 132 133 } 134 135 printf("%s\n",solve() ? "YES" : "NO"); 136 //cout << "Hello world!" << endl; 137 return 0; 138 }