【POJ】3678 Katu Puzzle
简单2-SAT。
1 /* 3678 */ 2 #include <iostream> 3 #include <algorithm> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 using namespace std; 8 9 #define MAXN 1005 10 #define MAXE 1000005 11 12 typedef struct { 13 int v, next; 14 } Edge_t; 15 16 int pre[MAXN*2], low[MAXN*2]; 17 int bn[MAXN*2]; 18 int dfs_clock, block; 19 int S[MAXN*2], top; 20 int head[MAXN*2], L; 21 Edge_t E[MAXE]; 22 int n, m, n2; 23 int a[MAXE], b[MAXE], c[MAXE]; 24 char op[MAXE]; 25 26 void addEdge(int u, int v) { 27 E[L].v = v; 28 E[L].next = head[u]; 29 head[u] = L++; 30 } 31 32 void init() { 33 dfs_clock = block = top = L = 0; 34 memset(pre, 0, sizeof(int)*n2); 35 memset(bn, 0, sizeof(int)*n2); 36 memset(head, -1, sizeof(int)*n2); 37 } 38 39 void dfs(int u) { 40 int i, j, k, v; 41 42 S[top++] = u; 43 pre[u] = low[u] = ++dfs_clock; 44 for (i=head[u]; i!=-1; i=E[i].next) { 45 v = E[i].v; 46 if (!pre[v]) { 47 dfs(v); 48 low[u] = min(low[u], low[v]); 49 } else if (!bn[v]) { 50 low[u] = min(low[u], pre[v]); 51 } 52 } 53 if (low[u] == pre[u]) { 54 ++block; 55 do { 56 bn[S[--top]] = block; 57 } while (S[top]!=u); 58 } 59 } 60 61 62 63 int main() { 64 int i, j, k; 65 int ii, jj; 66 char cmd[8]; 67 bool flag; 68 69 #ifndef ONLINE_JUDGE 70 freopen("data.in", "r", stdin); 71 freopen("data.out", "w", stdout); 72 #endif 73 74 while (scanf("%d %d",&n,&m)!=EOF) { 75 n2 = n+n; 76 for (i=0; i<m; ++i) { 77 scanf("%d %d %d %s", &a[i], &b[i], &c[i], cmd); 78 op[i] = cmd[0]; 79 } 80 flag = true; 81 for (k=0; flag&&k<32; ++k) { 82 init(); 83 for (i=0; i<m; ++i) { 84 ii = a[i]+a[i]; 85 jj = b[i]+b[i]; 86 if (op[i] == 'A') { 87 // and 88 if (c[i] & (1<<k)) { 89 addEdge(ii, ii+1); 90 addEdge(ii+1, jj+1); 91 addEdge(jj, jj+1); 92 addEdge(jj+1, ii+1); 93 } else { 94 addEdge(ii+1, jj); 95 addEdge(jj+1, ii); 96 } 97 } else if (op[i] == 'O') { 98 // or 99 if (c[i] & (1<<k)) { 100 addEdge(ii, jj+1); 101 addEdge(jj, ii+1); 102 } else { 103 addEdge(ii, jj); 104 addEdge(jj, ii); 105 addEdge(ii+1, ii); 106 addEdge(jj+1, jj); 107 } 108 } else if (op[i] == 'X') { 109 // xor 110 if (c[i] & (1<<k)) { 111 addEdge(ii, jj+1); 112 addEdge(ii+1, jj); 113 addEdge(jj, ii+1); 114 addEdge(jj+1, ii); 115 } else { 116 addEdge(ii, jj); 117 addEdge(ii+1, jj+1); 118 addEdge(jj, ii); 119 addEdge(jj+1, ii+1); 120 } 121 } 122 } 123 for (i=0; i<n2; ++i) 124 if (!pre[i]) 125 dfs(i); 126 for (i=0; flag&&i<n2; i+=2) 127 if (bn[i] == bn[i+1]) 128 flag = false; 129 } 130 if (flag) 131 puts("YES"); 132 else 133 puts("NO"); 134 } 135 136 return 0; 137 }