首页 > 代码库 > POJ 3678

POJ 3678

Katu Puzzle
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 7391   Accepted: 2717

Description

Katu Puzzle is presented as a directed graph G(VE) 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 ≤ X≤ 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:

AND 0 1
0 0 0
1 0 1
OR 0 1
0 0 1
1 1 1
XOR 0 1
0 0 1
1 1 0

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 (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 
  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 }
View Code