pku3678 Katu Puzzle
典型的2-SAT问题,每个数要么是0,要么是1,直接连边Tarjan即可
如果用x表示第x个数取0,x+n表示第x个数取1,
注意在x and y=1 时
连(x--->x+n)
(y--->y+n),
表示x必须取1,当x取到0时,由于与1有边相连,在一个强连通里,无解!
View Code
1 program pku3678(input,output);
2 type
3 node = ^link;
4 link = record
5 goal : longint;
6 next : node;
7 end;
8 var
9 stack,dfn,low,color : array[0..2100] of longint;
10 l : array[0..2100] of node;
11 instack : array[0..2100] of boolean;
12 top,cnt,colour : longint;
13 n,m : longint;
14 procedure add(xx,yy :longint );
15 var
16 t : node;
17 begin
18 new(t);
19 t^.goal:=yy;
20 t^.next:=l[xx];
21 l[xx]:=t;
22 end; { add }
23 procedure init;
24 var
25 ch : char;
26 i,x,y,z : longint;
27 s : ansistring;
28 begin
29 readln(n,m);
30 for i:=1 to m do
31 begin
32 read(x,y,z);
33 inc(x);
34 inc(y);
35 read(ch);
36 readln(s);
37 if s='AND' then
38 begin
39 if z=0 then
40 begin
41 add(x+n,y);
42 add(y+n,x);
43 end
44 else
45 begin
46 add(x,x+n);
47 add(y,y+n);
48 end;
49 end;
50 if s='OR' then
51 begin
52 if z=0 then
53 begin
54 add(x+n,x);
55 add(y+n,y); //
56 end
57 else
58 begin
59 add(x,y+n);
60 add(y,x+n);
61 end;
62 end;
63 if s='XOR' then
64 begin
65 if z=0 then
66 begin
67 add(x,y);
68 add(y,x);
69 add(y+n,x+n);
70 add(x+n,y+n);
71 end
72 else
73 begin
74 add(x+n,y);
75 add(y+n,x);
76 add(x,y+n);
77 add(y,x+n);
78 end;
79 end;
80 end;
81 end; { init }
82 procedure dfs(now :longint );
83 var
84 t : node;
85 begin
86 inc(cnt);
87 dfn[now]:=cnt;
88 low[now]:=cnt;
89 inc(top);
90 stack[top]:=now;
91 instack[now]:=true;
92 t:=l[now];
93 while t<>nil do
94 begin
95 if dfn[t^.goal]=0 then
96 begin
97 dfs(t^.goal);
98 if low[t^.goal]<low[now] then
99 low[now]:=low[t^.goal];
100 end
101 else
102 begin
103 if (instack[t^.goal])and(dfn[t^.goal]<low[now]) then
104 low[now]:=dfn[t^.goal];
105 end;
106 t:=t^.next;
107 end;
108 if low[now]=dfn[now] then
109 begin
110 inc(colour);
111 while true do
112 begin
113 instack[stack[top]]:=false;
114 color[stack[top]]:=colour;
115 dec(top);
116 if stack[top+1]=now then
117 break;
118 end;
119 end;
120 end; { dfs }
121 procedure main;
122 var
123 i : longint;
124 begin
125 for i:=1 to n*2 do
126 if dfn[i]=0 then
127 dfs(i);
128 end; { main }
129 procedure print;
130 var
131 i : longint;
132 begin
133 for i:=1 to n do
134 if color[i]=color[i+n] then
135 begin
136 writeln('NO');
137 exit;
138 end;
139 writeln('YES');
140 end; { print }
141 begin
142 init;
143 main;
144 print;
145 end.