POJ 3678 Katu Puzzle(强连通 法)
题意:给出a, b, c 和操作类型 (与或异或),问是否满足所有的式子
主要是建图:
对于 and , c == 1: 说明 a 和 b都是1,那么 0 就不能取, a' -> a , b' - > b ,因为 a 和 a'是对立事件,对于 a' - >a说明,a'如果成立,那么a也一定存在,显然这是不可能的所以a'不会 成立的。 c == 0 说明 a 和 b不全为1, a' -> b , b' -> a
对于 or, c == 1 :说明 a 和 b 不全为 0 , a' -> b, b' -> a c == 0 时 :说明 a 和 b 同时为0, a -> a' , b -> b‘ // a成立时候,a'可能不成立,所以a不会成立
对于xor, c == 1:说明 a 和 b不相等 , a -> b' , b -> a' , a' -> b, b' - >a // a b不相等有两张情况, a == 0 || b == 0 ; a == 1 || b == 1, 每一种建立两条边
c == 0:说明 a 和 b 相等, a' -> b', b' -> a' , a - > b, b -> a // a b相等有两种情况: a == b == 0, 或者 a == b == 1; 为什么不把前面ab同时为0 和 ab同时为1的情况合并呢, 合并肯定不对啊, a' -> a , a -> a',b- >b', b' - >b 什么啊这是=_=...
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 const int Maxn = 1000 * 2 + 10; 7 const int Maxm = 1000000 * 2 +10; 8 struct Edge 9 { 10 int to, Next; 11 }edge[Maxm]; 12 int head[Maxn], tot; 13 void init() 14 { 15 tot = 0; 16 memset(head, -1, sizeof(head)); 17 } 18 void addedge(int u, int v) 19 { 20 edge[tot].to = v; 21 edge[tot].Next = head[u]; 22 head[u] = tot++; 23 } 24 int low[Maxn], dfn[Maxn], Stack[Maxn], belong[Maxn]; 25 int Index, top; 26 int scc; 27 bool Instack[Maxn]; 28 void Tarjan(int u) 29 { 30 int v; 31 low[u] = dfn[u] = ++Index; 32 Stack[top++] = u; 33 Instack[u] = true; 34 for (int i = head[u]; i != -1; i = edge[i].Next) 35 { 36 v = edge[i].to; 37 if (!dfn[v]) 38 { 39 Tarjan(v); 40 if (low[u] > low[v]) 41 low[u] = low[v]; 42 } 43 else if (Instack[v] && low[u] > dfn[v]) 44 low[u] = dfn[v]; 45 } 46 if (low[u] == dfn[u]) 47 { 48 scc++; 49 do 50 { 51 v = Stack[--top]; 52 Instack[v] = false; 53 belong[v] = scc; 54 } while (u != v); 55 } 56 } 57 bool solvable(int n) 58 { 59 memset(dfn, 0, sizeof(dfn)); 60 memset(low, 0, sizeof(low)); 61 memset(belong, 0, sizeof(belong)); 62 memset(Instack, false, sizeof(Instack)); 63 Index = top = scc = 0; 64 for (int i = 0; i < n; i++) 65 { 66 if (!dfn[i]) 67 Tarjan(i); 68 } 69 for (int i = 0; i < n; i += 2) 70 { 71 if (belong[i] == belong[i ^ 1] ) 72 return false; 73 } 74 return true; 75 } 76 int main() 77 { 78 int n, m; 79 while (scanf("%d%d", &n, &m) != EOF) 80 { 81 init(); 82 int a, b, c; 83 char op[5]; 84 while (m--) 85 { 86 scanf("%d%d%d%s", &a, &b, &c, op); 87 a = a * 2; //这里要乘以2 88 b = b * 2; 89 if (strcmp(op, "AND") == 0) 90 { 91 if (c) 92 { 93 addedge(a, a ^ 1); 94 addedge(b, b ^ 1); 95 } 96 else 97 { 98 addedge(a ^ 1, b); 99 addedge(b ^ 1, a); 100 } 101 } 102 else if (strcmp(op, "OR") == 0) 103 { 104 if (c) 105 { 106 addedge(a, b ^ 1); 107 addedge(b, a ^ 1); 108 } 109 else 110 { 111 addedge(a ^ 1, a); 112 addedge(b ^ 1, b); 113 } 114 } 115 else if (strcmp(op, "XOR") == 0) 116 { 117 if (c) 118 { 119 addedge(a, b ^ 1); 120 addedge(b, a ^ 1); 121 addedge(a ^ 1, b); 122 addedge(b ^ 1, a); 123 } 124 else 125 { 126 addedge(a, b); 127 addedge(b, a); 128 addedge(a ^ 1, b ^ 1); 129 addedge(b ^ 1, a ^ 1); 130 } 131 } 132 } 133 134 if( solvable(n * 2) ) 135 printf("YES\n"); 136 else 137 printf("NO\n"); 138 139 } 140 return 0; 141 }