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
");
136        else
137             printf("NO
");
138 
139     }
140     return 0;
141 }
View Code
原文地址:https://www.cnblogs.com/zhaopAC/p/5373764.html