[题解]POJ 3678 Katu Puzzle
【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】
n个布尔变量Xi,现在有m个约束条件,给出Xi op Xj = c,给出每个i j c 和 op。其中op可能是AND,OR,XOR。要求这n个布尔变量是否存在一组可能的取值,使得满足所有的约束条件。
| op | c | Addedge |
| AND | 0 | i+n->j,j+n->i; |
| 1 | i->i+n,j->j+n; | |
| OR | 0 | i+n->i,j+n->j; |
| 1 | i->j+n,j->i+n; | |
| XOR | 0 | i+n->j+n.j->i,i->j,j+n->i+n; |
| 1 | i->j+n,j->i+n,i+n->j,j+n->i; |
细节参见代码:
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 using namespace std;
5 #define MAXN 1020*2
6 #define MAXM 1000020
7 struct node
8 {
9 int v;
10 node *next;
11 };
12 node edge[MAXN*MAXN];
13 node *cnt=&edge[0];
14 node *adj[MAXN];
15 int n,m;
16 int low[MAXN],dfn[MAXN],dcnt;
17 int stack[MAXN],top;
18 int Belong[MAXN],scc;
19 bool Instack[MAXN];
20 inline void Get_int(int &Ret)
21 {
22 char ch;
23 bool flag=false;
24 for(;ch=getchar(),ch<'0'||ch>'9';)
25 if(ch=='-')
26 flag=true;
27 for(Ret=ch-'0';ch=getchar(),ch>='0'&&ch<='9';Ret=Ret*10+ch-'0');
28 flag&&(Ret=-Ret);
29 }
30 inline void Addedge(int u,int v)
31 {
32 node *p=++cnt;
33 p->v=v;
34 p->next=adj[u];
35 adj[u]=p;
36 }
37 void Read()
38 {
39 //Get_int(n);
40 Get_int(m);
41 int i,j,k,r;
42 char cmd[8];
43 for(k=1;k<=m;k++)
44 {
45 Get_int(i);i++;
46 Get_int(j);j++;
47 Get_int(r);
48 scanf("%s",cmd);
49 if(cmd[0]=='A')
50 {
51 if(!r)
52 {
53 Addedge(i+n,j);
54 Addedge(j+n,i);
55 }
56 else
57 {
58 Addedge(i,i+n);
59 Addedge(j,j+n);
60 }
61 }
62 else if(cmd[0]=='O')
63 {
64 if(!r)
65 {
66 Addedge(i+n,i);
67 Addedge(j+n,j);
68 }
69 else
70 {
71 Addedge(i,j+n);
72 Addedge(j,i+n);
73 }
74 }
75 else
76 {
77 if(!r)
78 {
79 Addedge(i+n,j+n);
80 Addedge(j,i);
81 Addedge(i,j);
82 Addedge(j+n,i+n);
83 }
84 else
85 {
86 Addedge(i,j+n);
87 Addedge(j,i+n);
88 Addedge(i+n,j);
89 Addedge(j+n,i);
90 }
91 }
92 }
93 }
94 void Tarjan(int u)
95 {
96 int v;
97 dfn[u]=low[u]=++dcnt;
98 stack[++top]=u;
99 Instack[u]=true;
100 for(node *p=adj[u];p;p=p->next)
101 {
102 v=p->v;
103 if(!dfn[v])
104 {
105 Tarjan(v);
106 low[u]=min(low[u],low[v]);
107 }
108 else if(Instack[v])
109 low[u]=min(low[u],dfn[v]);
110 }
111 if(low[u]==dfn[u])
112 {
113 scc++;
114 do
115 {
116 v=stack[top];
117 top--;
118 Instack[v]=false;
119 Belong[v]=scc;
120 }while(v!=u);
121 }
122 }
123 bool Work()
124 {
125 int i;
126 for(i=1;i<=n*2;i++)
127 if(!dfn[i])
128 Tarjan(i);
129 for(i=1;i<=n;i++)
130 if(Belong[i]==Belong[i+n])
131 return false;
132 return true;
133 }
134 void Print()
135 {
136 if(Work())
137 printf("YES\n");
138 else
139 printf("NO\n");
140 }
141 inline void Pre()
142 {
143 memset(edge,0,sizeof(edge));
144 cnt=&edge[0];
145 memset(adj,0,sizeof(adj));
146 memset(low,0,sizeof(low));
147 memset(dfn,0,sizeof(dfn));
148 dcnt=0;
149 memset(stack,0,sizeof(stack));
150 top=0;
151 memset(Belong,0,sizeof(Belong));
152 scc=0;
153 memset(Instack,false,sizeof(Instack));
154 }
155 int main()
156 {
157 while(scanf("%d",&n)!=EOF)
158 {
159 Pre();
160 Read();
161 Print();
162 }
163 return 0;
164 }

浙公网安备 33010602011771号