题目: | Wedding | |
来源: | Pku 3648 | |
题目大意: | N对点,M对矛盾,1号点必须选,问和2号点在一边的点有谁,数据以0 0结束 | |
数据范围: |
| |
样例: | 10 6 3h 7h 5w 3w 7h 6w 8w 3w 7h 3w 2w 5h 0 0 | 1h 2h 3w 4h 5h 6h 7h 8h 9h |
做题思路: | 运用一天时间突破了在学习运用2-sat上的障碍,然后这道题差点毁了我的努力,真 是一朝交错题,十年对标程。Special judge让我对样例很无语。这道题把矛盾连 边,然后把1、2连边,然后做kosaraju,然后判断是否矛盾,不矛盾就自底向上拓 扑然后输出就好。程序标准套模块不做解释了先。。 | |
知识点: | 2-sat、kosaraju |
type
edge=record
y,next:longint;
end;
var
first_1,first_2,q,col,q2:array[0..20000]oflongint;
b:array[0..20000]of boolean;
a_1,a_2:array[0..40000]of edge;
n,tot_1,tot_2,color,time,m:longint;
procedure ad_edge_1(x,y:longint);
begin
inc(tot_1);
a_1[tot_1].y:=y;
a_1[tot_1].next:=first_1[x];
first_1[x]:=tot_1;
end;
procedure ad_edge_2(x,y:longint);
begin
inc(tot_2);
a_2[tot_2].y:=y;
a_2[tot_2].next:=first_2[x];
first_2[x]:=tot_2;
end;
procedure init;
var
i,x1,y1,x2,y2,j,p,t:longint;
s:string;
begin
fillchar(first_1,sizeof(first_1),0);
fillchar(first_2,sizeof(first_2),0);
tot_1:=0;tot_2:=0;
fori:=1 to m do
begin
readln(s);
p:=pos(' ',s);
t:=0;
forj:=1 to p-2 do t:=t*10+ord(s[j])-ord('0');
inc(t);
x1:=t*2;
t:=0;
ifs[p-1]='h' then dec(x1);
forj:=p+1 to length(s)-1 do t:=t*10+ord(s[j])-ord('0');
inc(t);
y1:=t*2;
ifs[length(s)]='h' then dec(y1);
ifx1>y1 then
begin
t:=x1;x1:=y1;y1:=t;
end;
ifodd(x1) then x2:=x1+1 else x2:=x1-1;
ifodd(y1) then y2:=y1+1 else y2:=y1-1;
ad_edge_1(x1,y2);
ad_edge_2(y2,x1);
ad_edge_1(y1,x2);
ad_edge_2(x2,y1);
end;
ad_edge_1(2,1);
ad_edge_2(1,2);
end;
procedure dfs_1(x:longint);
var
t:longint;
begin
b[x]:=true;
t:=first_1[x];
whilet>0 do
begin
ifnot b[a_1[t].y] then dfs_1(a_1[t].y);
t:=a_1[t].next;
end;
inc(time);
q[time]:=x;
end;
procedure dfs_2(x:longint);
var
t:longint;
begin
col[x]:=color;
t:=first_2[x];
whilet>0 do
begin
ifcol[a_2[t].y]=0 then dfs_2(a_2[t].y);
t:=a_2[t].next;
end;
end;
procedure kosaraju;
var
i:longint;
begin
fillchar(b,sizeof(b),false);
fillchar(q,sizeof(q),0);
fillchar(q2,sizeof(q2),0);
fillchar(col,sizeof(col),0);
time:=0;
fori:=1 to 2*n do
ifnot b[i] then dfs_1(i);
color:=0;
fori:=2*n downto 1 do
ifcol[q[i]]=0 then
begin
inc(color);
q2[color]:=q[i];
dfs_2(q[i]);
end;
end;
procedure delete(x:longint);
var
t:longint;
begin
q[x]:=2;
t:=first_2[x];
whilet>0 do
begin
if(q[a_2[t].y]=0)and(col[x]=col[a_2[t].y]) then delete(a_2[t].y);
t:=a_2[t].next;
end;
end;
procedure sat(x:longint);
var
t:longint;
begin
q[x]:=1;
t:=first_2[x];
whilet>0 do
begin
if(q[a_2[t].y]=0)and(col[x]=col[a_2[t].y]) then sat(a_2[t].y);
t:=a_2[t].next;
end;
ifodd(x) then delete(x+1) else delete(x-1);
end;
procedure outit;
var
i:longint;
begin
fori:=3 to 2*n do
ifq[i]=2 then
begin
write((i+1) div 2-1);
ifodd(i) then write('h') else write('w');
write(' ');
end;
writeln;
end;
procedure main;
var
i:longint;
begin
fori:=1 to n do
ifcol[2*i-1]=col[2*i] then
begin
writeln('bad luck');
exit;
end;
fillchar(q,sizeof(q),0);
fori:=color downto 1 do
ifq[q2[i]]=0 then sat(q2[i]);
outit;
end;
begin
readln(n,m);
whilenot (m+n=0) do
begin
init;
kosaraju;
main;
readln(n,m);
end;
end.
题目来源:
http://poj.org/problem?id=3648