这道题和今年GDKOI的Day2T2很像(然而gdkoi的题用网络流可以A,这道题只能拿30)。
网址:http://www.lydsy.com/JudgeOnline/problem.php?id=1854
题目:
很显然,我们可以立即想到一种解法:如果第i个武器的属性是(a,b),那么就连i->a,i->b两条边,然后就跑网络流。为了确保要从1开始连续攻击,就可以二分答案,用网络流来判断,因为如果能从1打到n,就肯定能从1打到n-1(废话)。判断就是每次只让1~mid的属性值流过去,看一下最后的最大流是否为mid,就知道能不能从1打到mid。
代码:
var f,d,q,x,y:array[0..1000010]of longint; a,b,ne:array[0..2000010]of longint; n,k,nn,i,j,h,t,p,l,r,m,ans:longint; procedure add(x,y,z:longint); begin a[p]:=y; b[p]:=z; ne[p]:=f[x]; f[x]:=p; inc(p); a[p]:=x; b[p]:=0; ne[p]:=f[y]; f[y]:=p; inc(p); end; function dfs(now,ll:longint):longint; var i,p:longint; begin if now=nn then exit(ll); i:=f[now]; while i>=0 do begin if(b[i]>0)and(d[a[i]]=d[now]+1)then begin if ll<b[i] then p:=dfs(a[i],ll) else p:=dfs(a[i],b[i]); b[i]:=b[i]-p; b[i xor 1]:=b[i xor 1]+p; if p>0 then exit(p); end; i:=ne[i]; end; exit(0); end; begin read(n); for i:=1 to n do read(x[i],y[i]); l:=0; r:=10001; nn:=n+10001; while l+1<r do begin p:=0; m:=(l+r)>>1; for i:=0 to nn do f[i]:=-1; for i:=1 to n do begin add(i,n+x[i],1); add(i,n+y[i],1); end; for i:=1 to n do add(0,i,1); for i:=1 to m do add(n+i,nn,1); ans:=0; while true do begin for i:=0 to nn do d[i]:=0; h:=1; t:=1; q[1]:=0; d[0]:=1; repeat i:=f[q[h]]; while i>=0 do begin if(b[i]>0)and(d[a[i]]=0)then begin inc(t); q[t]:=a[i]; d[a[i]]:=d[q[h]]+1; end; i:=ne[i]; end; inc(h); until h>t; if d[nn]=0 then break; repeat p:=dfs(0,1<<25); ans:=ans+p; until p=0; end; if m=ans then l:=m else r:=m; end; writeln(l); end.