Katu Puzzle
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
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 }
POJ 3678,码迷,mamicode.com