Pku 3648 Wedding

7 篇文章 0 订阅
6 篇文章 0 订阅

题目:

 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值