JSOI2010 满汉全席

强省江苏也有这种比较水的送分题,囧

典型的2-SAT问题,对于某一种材料,要么做满菜,要么做汉菜,

连边时枚举评委,两者有相同编号的矛盾菜式则连边,不满足一得第一个要求就得满足一的第二个要求

h1 m2

m1 h3

由于材料1只有一种,所以做h1就必须做h3,做m1就必须做m2

晒代码

View Code
  1 program jsoi2010(input,output);
2 type
3 link=^node;
4 node=record
5 goal:longint;
6 next:link;
7 end;
8 node2=record
9 one,two:longint;
10 end;
11 var
12 l:array[0..500] of link;
13 stack,low,dfn,color:array[0..500] of longint;
14 instack:array[0..500] of boolean;
15 ask:array[0..1100] of node2;
16 n,m,cnt,k,p,top,colour:longint;
17 procedure clean;
18 var
19 i:longint;
20 begin
21 for i:=1 to 500 do
22 l[i]:=nil;
23 fillchar(stack,sizeof(stack),0);
24 fillchar(instack,sizeof(instack),false);
25 fillchar(color,sizeof(color),0);
26 fillchar(dfn,sizeof(dfn),0);
27 fillchar(low,sizeof(low),0);
28 cnt:=0;
29 top:=0;
30 colour:=0;
31 end;
32 procedure add(xx,yy:longint);
33 var
34 t:link;
35 begin
36 new(t);
37 t^.goal:=yy;
38 t^.next:=l[xx];
39 l[xx]:=t;
40 end;
41 procedure init;
42 var
43 i :longint;
44 ch:char;
45 begin
46 readln(n,m);
47 for i:=1 to m do
48 begin
49 read(ch);
50 read(ask[i].one);
51 if ch='h' then
52 inc(ask[i].one,n);
53 read(ch);
54 read(ch);
55 readln(ask[i].two);
56 if ch='h' then
57 inc(ask[i].two,n);
58 end;
59 end;
60 procedure make_graph;
61 var
62 i,j:longint;
63 begin
64 for i:=1 to n do
65 for j:=1 to m do
66 begin
67 if (ask[j].one=n+i) then
68 add(i,ask[j].two);
69 if (ask[j].two=n+i) then
70 add(i,ask[j].one);
71 end;
72 for i:=n+1 to n*2 do
73 for j:=1 to m do
74 begin
75 if (ask[j].one=i-n) then
76 add(i,ask[j].two);
77 if (ask[j].two=i-n) then
78 add(i,ask[j].one);
79 end;
80 end;
81 function dfs(now:longint):longint;
82 var
83 t:link;
84 begin
85 inc(cnt);
86 low[now]:=cnt;
87 dfn[now]:=cnt;
88 inc(top);
89 stack[top]:=now;
90 instack[now]:=true;
91 t:=l[now];
92 while t<>nil do
93 begin
94 if dfn[t^.goal]=0 then
95 begin
96 dfs(t^.goal);
97 if low[t^.goal]<low[now] then
98 low[now]:=low[t^.goal];
99 end
100 else
101 if (instack[t^.goal])and(dfn[t^.goal]<low[now]) then
102 low[now]:=dfn[t^.goal];
103 t:=t^.next;
104 end;
105 if dfn[now]=low[now] then
106 begin
107 inc(colour);
108 while true do
109 begin
110 color[stack[top]]:=colour;
111 instack[stack[top]]:=false;
112 dec(top);
113 if stack[top+1]=now then
114 break;
115 end;
116 end;
117 end;
118 procedure main;
119 var
120 i:longint;
121 begin
122 for i:=1 to n*2 do
123 if dfn[i]=0 then
124 dfs(i);
125 end;
126 procedure print;
127 var
128 i:longint;
129 begin
130 for i:=1 to n do
131 if color[i]=color[i+n] then
132 begin
133 writeln('BAD');
134 exit;
135 end;
136 writeln('GOOD');
137 end;
138 begin
139 readln(p);
140 for k:=1 to p do
141 begin
142 clean;
143 init;
144 make_graph;
145 main;
146 print;
147 end;
148 end.



posted @ 2012-02-26 17:01  Codinginging  阅读(410)  评论(0编辑  收藏  举报