就题目而言,这道题是裸的二分+最大流
但是这样是TLE的,我们考虑优化
1. 我们可以先贪心,这样二分的上界就可以
2. 最大流我们可以不急着跑增广路,我们可以先贪心一个流然后再跑增广路
但是我们发现上述优化还是不足以通过这题
我们考虑是不是sap不适合处理这张图(这是二分图)呢?确实是这样的
考虑到sap判断h[s]<t+1,但实际上二分图的增广路不可能太长,我们把这个条件改成h[s]<100
duang的一下,就飞快的跑过了(460ms)
而事实证明dinic似乎没有这种问题,因为根据证明,dinic跑二分图和HK算法是一样的复杂度
1 type node=record 2 po,next,flow:longint; 3 end; 4 5 var e:array[0..200010] of node; 6 w,pre,numh,p,h,cur,x,y:array[0..20010] of longint; 7 ans,t,i,n,m,l,r,mid,len,need:longint; 8 9 procedure add(x,y,f:longint); 10 begin 11 inc(len); 12 e[len].po:=y; 13 e[len].flow:=f; 14 e[len].next:=p[x]; 15 p[x]:=len; 16 end; 17 18 procedure build(x,y,f1,f2:longint); 19 begin 20 add(x,y,f1); 21 add(y,x,f2); 22 end; 23 24 function sap:longint; 25 var i,j,q,u,tmp:longint; 26 begin 27 fillchar(numh,sizeof(numh),0); 28 fillchar(h,sizeof(h),0); 29 for i:=0 to t do 30 cur[i]:=p[i]; 31 u:=0; sap:=0; 32 while (h[0]<t+1) and (h[0]<100) do //重要优化 33 begin 34 i:=cur[u]; 35 while i<>-1 do 36 begin 37 j:=e[i].po; 38 if (e[i].flow>0) and (h[u]=h[j]+1) then 39 begin 40 cur[u]:=i; 41 pre[j]:=u; 42 u:=j; 43 if u=t then 44 begin 45 inc(sap); 46 if sap=need then exit; 47 while u<>0 do 48 begin 49 u:=pre[u]; 50 j:=cur[u]; 51 dec(e[j].flow); 52 inc(e[j xor 1].flow); 53 end; 54 end; 55 break; 56 end; 57 i:=e[i].next; 58 end; 59 if i=-1 then 60 begin 61 dec(numh[h[u]]); 62 if numh[h[u]]=0 then exit; 63 i:=p[u]; 64 tmp:=t; 65 q:=-1; 66 while i<>-1 do 67 begin 68 j:=e[i].po; 69 if e[i].flow>0 then 70 if tmp>h[j] then 71 begin 72 q:=i; 73 tmp:=h[j]; 74 end; 75 i:=e[i].next; 76 end; 77 h[u]:=tmp+1; 78 inc(numh[h[u]]); 79 cur[u]:=q; 80 if u<>0 then u:=pre[u]; 81 end; 82 end; 83 end; 84 85 procedure swap(var a,b:longint); 86 var c:longint; 87 begin 88 c:=a; 89 a:=b; 90 b:=c; 91 end; 92 93 function check(h:longint):boolean; 94 var i:longint; 95 begin 96 len:=-1; 97 fillchar(p,sizeof(p),255); 98 need:=0; 99 for i:=1 to n do 100 w[i]:=h; 101 for i:=1 to m do //贪心初始流 102 begin 103 if w[x[i]]<w[y[i]] then swap(x[i],y[i]); 104 if w[x[i]]=0 then 105 begin 106 build(i,x[i]+m,1,0); 107 build(0,i,1,0); 108 inc(need); 109 end 110 else begin 111 dec(w[x[i]]); 112 build(0,i,0,1); 113 build(i,x[i]+m,0,1); 114 end; 115 build(i,y[i]+m,1,0); 116 end; 117 if need=0 then exit(true); 118 for i:=1 to n do 119 build(i+m,t,w[i],h-w[i]); 120 if sap=need then exit(true) else exit(false); 121 end; 122 123 begin 124 readln(n,m); 125 for i:=1 to m do 126 begin 127 readln(x[i],y[i]); 128 if w[x[i]]<w[y[i]] then inc(w[x[i]]) else inc(w[y[i]]); 129 end; 130 for i:=1 to n do 131 if w[i]>r then r:=w[i]; //贪心上界 132 t:=n+m+1; 133 l:=0; 134 while l<=r do 135 begin 136 mid:=(l+r) shr 1; 137 if check(mid) then 138 begin 139 ans:=mid; 140 r:=mid-1; 141 end 142 else l:=mid+1; 143 end; 144 writeln(ans); 145 end.
时间: 2024-10-20 22:20:01