Pku 2723 Get Luffy Out

来源:互联网 发布:拉萨联通网络包年 编辑:程序博客网 时间:2024/05/18 02:44

题目:

 Get Luffy Out

来源:

 Pku 2723

题目大意:

 N*2种类型的钥匙,M道门,每道门可以用两种类型之一的钥匙打开,门必须按顺序  打开,问最多可以打开几道门

数据范围:

 N (1 <= N <= 210) and M (1 <= M <= 211)

样例:

 3 6
 0 3
 1 2
 4 5
 0 1
 0 2
 4 1
 4 2
 3 5
 2 2
 0 0
4

做题思路:

 先把编号进行预处理,每个门上的锁变成编号从小到大。
 构图:
 1)若X和Y在同一个门上,则X向Y'连一条边,Y向X'连一条边。
 2)若两个X在同一个门上,则X必然会使用,则X'向X连一条边。

知识点:

 二分答案、2-sat验证、kosaraju

type edge=record y,next:longint; end;//====================================================var a1,a2:array[0..6000]of edge; first1,first2,q1,f,a,t1,t2:array[0..6000]oflongint; time,tot1,tot2,n,m,mm:longint;//=========================================================procedure build1(x,y:longint);begin inc(tot1); a1[tot1].y:=y; a1[tot1].next:=first1[x]; first1[x]:=tot1;end;//==================================================================procedure build2(x,y:longint);begin inc(tot2); a2[tot2].y:=y; a2[tot2].next:=first2[x]; first2[x]:=tot2;end;//============================================================procedure init;var i,x,y,t:longint;begin fillchar(a,sizeof(a),0); fillchar(t1,sizeof(t1),0); fillchar(t2,sizeof(t2),0); fori:=1 to n do  begin  readln(x,y);  a[x]:=2*i-1;{<要是对应编号>}  a[y]:=2*i;  end; fori:=1 to m do  begin  readln(x,y);   ifx>y then   begin    t:=x;x:=y;y:=t;   end;  t1[i]:=a[x];t2[i]:=a[y];  end;end;//===========================================================procedure dfs1(x:longint);var t:longint;begin f[x]:=1; t:=first1[x]; whilet>0 do  begin   iff[a1[t].y]=0 then dfs1(a1[t].y);  t:=a1[t].next;  end; inc(time); q1[time]:=x;end;//==========================================================procedure dfs2(x:longint);var t:longint;begin f[x]:=time; t:=first2[x]; whilet>0 do  begin   iff[a2[t].y]=0 then dfs2(a2[t].y);  t:=a2[t].next;  end;end;//==============================================================procedure kosaraju;var i:longint;begin time:=0; fillchar(f,sizeof(f),0); fori:=1 to n*2 do  iff[i]=0 then dfs1(i); time:=0; fillchar(f,sizeof(f),0); fori:=n*2 downto 1 do  iff[q1[i]]=0 then  begin   inc(time);   dfs2(q1[i]);   end;end;procedure setup;var i,x1,x2,y1,y2:longint;begin fillchar(first1,sizeof(first1),0); fillchar(first2,sizeof(first2),0); fillchar(a1,sizeof(a1),0); fillchar(a2,sizeof(a2),0); tot1:=0;tot2:=0; fori:=1 to mm do  begin  x1:=t1[i];  y1:=t2[i];   ifodd(x1) then x2:=x1+1 else x2:=x1-1;   ifodd(y1) then y2:=y1+1 else y2:=y1-1;   ifx1<>y1 then   begin    build1(x1,y2);build2(y2,x1);    build1(y1,x2);build2(x2,y1);    end   else   begin    build1(x1,x2);build2(x2,x1);   end;  end;end;//=======================================================function pd(x:longint):boolean;var i:longint;begin mm:=x; setup; kosaraju; fori:=1 to n do  if(f[2*i]=f[2*i-1]) then  begin   exit(false);   end; exit(true);end;//==========================================================procedure main;var l,r,mid:longint;begin l:=1;r:=m; whilel<r do  begin  mid:=(l+r+1)shr 1;   ifnot pd(mid) then r:=mid-1   else l:=mid;  end; writeln(l);end;begin readln(n,m); whilen+m<>0 do  begin  init;  kosaraju;  main;  readln(n,m);  end;end.
题目来源:http://poj.org/problem?id=2723

原创粉丝点击