POJ2455 Secret Milking Machine ——二分答案+网络流——Pku2455

思路:二分答案,用权值比二分出来的答案小的边来建图。网络流判定的是是否能够满足找到t条路径。

CODE

Program Secret;//By_Poetshy   

Const  

    maxn=40000;  

Var  

    i,j,k,m,n,p,t,d         :Longint;  

    pre,other,last,data     :Array[1..maxn*2]of Longint;  

    a,b                     :Array[1..200]of Longint;  

    v                       :Array[1..200]of Boolean;  

    f,c                     :Array[1..200,1..200]of Longint;  

    l,r,mid,ans,max         :Longint;  

  

Function Min(i,j:Longint):Longint;  

begin  

    if i<j then exit(i);exit(j);  

end;  

  

Function Check(i:Longint):Boolean;  

var j,k,p,q,sum,head,tail   :Longint;  

    seq                     :Array[1..maxn]of Longint;  

begin  

    fillchar(f,sizeof(f),0);  

    fillchar(c,sizeof(c),0);  

    for p:=1 to n do  

        begin  

            j:=last[p];  

            while j<>0 do  

                begin  

                    k:=other[j];  

                    if data[j]<=i then inc(c[p,other[j]]);  

                    j:=pre[j];  

                end;  

        end;  

    repeat  

        fillchar(v,sizeof(v),0);  

        head:=0;tail:=1;seq[1]:=1;  

        a[1]:=0;b[1]:=maxlongint;  

        v[1]:=true;  

        while head<tail do  

            begin  

                inc(head);p:=seq[head];  

                for q:=1 to n do  

                    if (c[p,q]<>0)and(f[p,q]<c[p,q])and(not v[q])then  

                        begin  

                            v[q]:=true;  

                            a[q]:=p;b[q]:=Min(c[p,q]-f[p,q],b[p]);  

                            inc(tail);seq[tail]:=q;  

                        end;  

                if seq[tail]=n then break;  

            end;  

        if v[n] then  

            begin  

                p:=n;  

                while p<>0 do  

                    begin  

                        if a[p]<>0 then inc(f[a[p],p],b[n]);  

                        p:=a[p];  

                    end;  

            end;  

    until not v[n];  

    sum:=0;  

    for p:=1 to n-1 do inc(sum,f[p,n]);  

    if sum>=t then exit(true);  

    exit(false);  

end;  

  

BEGIN  

    readln(n,p,t);  

    for i:=1 to p do  

        begin  

            readln(m,j,d);  

            inc(k);pre[k]:=last[m];last[m]:=k;other[k]:=j;data[k]:=d;  

            inc(k);pre[k]:=last[j];last[j]:=k;other[k]:=m;data[k]:=d;  

            if d>max then max:=d;  

        end;  

    l:=0;r:=max;  

    while l<=r do  

        begin  

            mid:=(l+r)>>1;  

            if check(mid) then  

                begin  

                    ans:=mid;  

                    r:=mid-1;  

                end else l:=mid+1;  

        end;  

    writeln(ans);  

END.  

你可能感兴趣的:(mac)