重点是怎么建图,纠结了一天看2-SAT的资料...
a 表示1, a'表示0,则:
1、a and b = 1, a' -> a, b'-> b (a b 同时为1 )
2、a and b = 0, a -> b', b -> a' (a b 不同时为1)
3、a or b = 1, a' -> b, b' -> a (a b不同时为0)
4、a or b = 0, a -> a', b -> b' (a b同时为0 同1)
5、a xor b = 1, a -> b', b -> a', a' -> b, b' -> a (a b 不相等)
6、a xor b = 0, a -> b, b -> a, a' -> b', b' -> a' (a b 相等)
以1为例:a ^ b = (a V a) ^ (b V b) 因为 A V B 建图为 ~A -> B, ~B -> A, 这里把B换成A就是 ~A -> A,同理, ~B -> B
另一个关于a and b = 1, a' -> a, b'-> b 的解释:http://blog.sina.com.cn/s/blog_68629c7701010gf1.html
渣代码:
View Code
1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <stack>
5 #include <string>
6
7 using namespace std;
8
9 const int N = 2005;
10 const int M = 1000005;
11
12 struct node {
13 int next;
14 int to;
15 } g[M];
16
17 int head[N], scc[N];
18 int dfn[N], low[N];
19 int t, cnt, ind;
20 bool vis[N];
21
22 stack<int> s;
23
24 void init() {
25 for(int i = 0; i < N; i++) {
26 head[i] = scc[i] = dfn[i] = low[i] = vis[i] = 0;
27 }
28 t = 1; ind = cnt = 0;
29 }
30
31 void add(int u, int v) {
32 g[t].to = v; g[t].next = head[u]; head[u] = t++;
33 }
34
35 void tarjan(int u) {
36 int v, i;
37 dfn[u] = low[u] = ++ind;
38 vis[u] = true; s.push(u);
39 for(i = head[u]; i; i = g[i].next) {
40 v = g[i].to;
41 if(!dfn[v]) {
42 tarjan(v);
43 low[u] = min(low[u], low[v]);
44 } else if(vis[v]) {
45 low[u] = min(low[u], dfn[v]);
46 }
47 }
48 if(low[u] == dfn[u]) {
49 cnt++;
50 do {
51 v = s.top(); s.pop();
52 scc[v] = cnt;
53 vis[v] = false;
54 } while(v != u);
55 }
56 }
57
58 int main() {
59 //freopen("data.in", "r", stdin);
60
61 int n, m, i;
62 int a, b, c;
63 bool flag;
64 string str;
65 while(~scanf("%d%d", &n, &m)) {
66 init();
67 while(m--) {
68 cin >> a >> b >> c >> str;
69 //cout << a << " " << b << " " << c << " " << str << endl;
70 if(str == "AND") {
71 if(c) {add(a, a + n); add(b, b + n);}
72 else {add(a + n, b); add(b + n, a);}
73 } else if(str == "OR") {
74 if(c) {add(a, b + n); add(b, a + n);}
75 else {add(a + n, a); add(b + n, b);}
76 } else if(str == "XOR") {
77 if(c) {add(a + n, b); add(a, b + n); add(b, a + n); add(b + n, a);}
78 else {add(a, b); add(b, a); add(a + n, b + n); add(b + n, a + n);}
79 }
80 }
81 for(i = 0; i < 2*n; i++) {
82 if(!dfn[i]) tarjan(i);
83 }
84 for(flag = true, i = 0; i < n; i++) {
85 if(scc[i] == scc[i + n]) {
86 cout << "NO" << endl;
87 flag = false; break;
88 }
89 }
90 if(flag) cout << "YES" << endl;
91 }
92 return 0;
93 }