1、var delta:longint;begindelta:=maxlongint;k:=n;while prek-1 do=min(delta,cprek,k);=prek;end;inc(maxflow,delta);dec(cprek,k,delta);inc(ck,prek,delta);2. 深度优先搜索或宽度优先搜索寻找增广轨(时间复杂度O(V2*E) 。【深度优先搜索的参考过程】function find(k:longint):boolean;var i:integer;if k=n then exit(true);for i:=1 to n doif ck,i0 thenprei
2、:=k;if find(i) then exit(true);exit(false);3. 最短增广路算法(SAP:Shortest Augmenting Path Algorithm)(时间复杂度O(V*E2) )。基本思想是:依次通过标号差为1的结点找增广轨,以保证找到的增广路是当前最短的。如果标号出现断链,则需要进行调整来维持。如果ci,j0且di-dj=1那么叫允许弧,先从汇点出发宽度遍历所有结点,求出所有结点到汇点所经过的得最少路径数,用宽搜实现。procedure SAP;var pre:array0.maxn+1 of longint;i:=1;while di=true;pre
3、j:=i;=j;break;if find then /找到允许弧,继续寻找if i=n thentrack_back; /到达汇点,路径完整,求这条路上的最大流continue;di:=maxint; /如果没找到允许弧,调整位与之相邻的最小的dj+1if (ci,j0) and (didj+1) then di:=dj+1;if i0)and(vi=false)then begin inc(e); if e2000 then e: qe: pe:=s; vi: end; if s2*(n+m) then break;2000 then s: until s=e; exit(false);
4、readln(n,m,k);=1 to k do begin readln(a,b); b:=b+n; maxa,b: maxb,a:=1 to n do begin max0,i: maxi,0:=1 to m do begin maxn+i,n+m+1: maxn+m+1,n+i: while bfs do begin i: inc(sum); j:=pi; inc(mapqi,qj); dec(mapqj,qi); until pi=0; writeln(sum);end.例16-2 ditch【题目来源:USACO Training 4.2 Drainage Ditches】在农夫约翰
5、的农场上,每逢下雨,Bessie最喜欢的三叶草地就积聚了一潭水。这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间。 因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没的烦恼(不用担心,雨水会流向附近的一条小溪)。作为一名一流的技师,农夫约翰已经在每条 排水沟的一端安上了控制器,这样他可以控制流入排水沟的水流量。农夫约翰知道每一条排水沟每分钟可以流过的水量,和排水系统的准确布局(起点为水潭而终点为小溪的一张网)。需要注意的是,有些时候从一处到另一处不只有一条排水沟。根据这些信息,计算从水潭排水到小溪的最大流量。对于给出的每条排水沟,雨水只能沿着一个方向流动,注意可能会出现
6、雨水环形流动的情形。I【输入】(file ditch.in) 第1行: 两个用空格分开的整数N (0 = N = 200) 和 M (2 = M = 200)。N是农夫John已经挖好的排水沟的数量,M是排水沟交叉点的数量。交点1是水潭,交点M是小溪。第二行到第N+1行: 每行有三个整数,Si, Ei, 和 Ci。Si 和 Ei (1 = Si, Ei = M) 指明排水沟两端的交点,雨水从Si 流向Ei。Ci (0 = Ci = 10,000,000)是这条排水沟的最大容量。【输出】 (file ditch.out) 输出一个整数,即排水的最大流量。5 41 2 401 4 202 4 20
7、2 3 303 4 10 【输出样例】50这个题是典型的最大流问题,由于数据规模很小,我们可以使用BFS找增广路。每次找增广路的时候把汇能增广的流量加入到最大流中,直到无法增广为止。program ditch;const MXN=207; n,m,s,t,i,u,v,w: f,c:array1.MXN,1.MXN of longint; pre,low,q:array1.MXN of longint; vis:array1.MXN of boolean;function maxflow: flow,l,r,u,v: flow: fillchar(low,sizeof(low),0); fill
8、char(vis,sizeof(vis),0);viss: fillchar(q,sizeof(q),0);lows: q1:l:r:=2; while lfu,v then begin visv:prev:=u; inc(r);qr:=v; lowv:=cu,v-fu,v; if lowvlowu then lowv:=lowu; end; end; if lowt0 then begin u:=t; repeat fpreu,u:=fpreu,u+lowt; fu,preu:=fu,preu-lowt; u:=preu; until u=s; flow:=flow+lowt; until
9、lowt=0; exit(flow); assign(input,ditch.in); assign(output,ditch.out reset(input);rewrite(output); read(m,n);t:=1 to m do begin read(u,v,w); cu,v:=cu,v+w; writeln(maxflow); close(input);close(output);例16-3 K-联赛K-联赛职业足球俱乐部的球迷们都是有组织的训练有素的啦啦队员,就像红魔啦啦队一样(2002年韩日世界杯上韩国队的啦啦队)。这个赛季,经过很多场比赛以后,球迷们希望知道他们支持的球队是
10、否还有机会赢得最后的联赛冠军。换句话说,球队是否可以通过某种特定的比赛结果最终取得最高的积分(获胜场次最多)。(允许出现多支队并列第一的情况。)现在,给出每个队的胜负场数,wi和di,分别表示teami的胜场和负场(1in)。还给出ai,j,表示teami和teamj之间还剩多少场比赛要进行(1i,jn)。这里,n表示参加联赛的队数,所有的队分别用1,2,n来编号。你的任务是找出所有还有可能获得冠军的球队。所有队参加的比赛数是相同的,并且为了简化问题,你可以认为不存在平局(比赛结果只有胜或负两种)。第一行一个整数n(1n25),表示联赛中的队数。第二行2n个数,w1,d1,w2,d2,wn,d
11、n,所有的数不超过100。第3到n+2行每行n个数,第i+2行的n个数为ai,1,ai,2,ai,n。所有的数都不超过10。ai,j=aj,i,如果i=j,则ai,j=0。若干行,输出所有可能获得冠军的球队,按其编号升序输出,每行一个。32 0 1 1 0 20 2 22 0 22 2 01 2 3对于队伍i,如果存在时期总分最高的方案,那么显然至少存在一种队伍i剩下比赛全胜而最终总分最高的方案,因此先使得i的剩余比赛均获胜,之后因为其他队伍得分不能超过i,而每场比赛都必须决出胜负。对此,可以构图,对于a,b的一场比赛,从a向a,b各引一条容量为一的边,从一个源向所有a引容量无限的边,之后根据
12、各队不同情况确定各a到汇的边的容量,求出最大流即是最多可以决出胜负的场数,显然地,只有当此场数等于比赛总数时,i才可以夺冠。 map,m:array0.50,0.51of longint; a:array1.25,1.25of longint; w:array1.25of longint;array0.51of boolean; q,pre,t:array0.52of longint; n,i,j,k,l,r,x,h,sum,max,flow: function min(a,b: if ab then exit(a) else exit(b); readln(n);=1 to n do rea
13、d(wi,x); for j:=1 to n do begin read(ai,j); if i0)then begin prei: ti:=min(tql,mql,i); inc(r); qr: if vh then break; until l=r; if vh then begin=h; inc(flow,th); while prer-1 do begin dec(mprer,r,th); inc(mr,prer,th);=prer; until not(vh); if sum-max+wk=flow then writeln(k);例16-4破坏石油运输系统问题【题目来源:RQNOJ
14、 P306】【问题描述】 某组织打算摧毁发烂稀国的石油运输系统。该系统可以看成一个运输网络,由许多结点和连接结点的管道组成。只有地点A生产石油,生产的石油通过管道运输到地点B,石油不能在中间点累积。管道是双向的,每条管道连接两个不同的结点,每两个结点之间只有一条管道连接。每条管道有一个抗压指数,当石油的流量超过这个数管道就会爆炸。A地生产石油的速度是很快的,但由于抗压指数的问题,能运到B的有一个上限。发烂稀国比较贪婪,他们采用了使他们获得最多石油的运输方案。某组织有一个特殊的物质,能使一条管道的抗压指数下降1。作为该组织的首席程序员,你的任务就是告诉领导,让那些管道的抗压指数下降,一定可以摧毁
15、发烂稀国的石油运输网络。第1行包含四个整数n,m,s,t,表示有n个结点(编号为1,2,3,n),m条管道,s和t分别是A地和B地的编号。2=n=130, 0=m=n (n-1)/2, 1= s,t = n。接下来m行,每行描述一条管道,包含3个整数i, j, c。i, j 分别为管道连接的2个结点。C为该条管道的抗压指数。1=i, j=n, 1=c =10000。 【输出】第1行输出抗压指数减少1就爆炸的管道的条数k。接下来k行每行输出一个整数p(1=p b then exit(b) else exit(a);function dfs(u,flow: v,tmp,ans: if (u=t)
16、then exit(flow); ans: for v:=1 to n do if (guv0)and (du-1=dv) then tmp:=dfs(v,min(flow-ans,guv); dec(guv,tmp);inc(gvu,tmp); if (cuv0) then inc(fuv,tmp) else inc(fvu,tmp); inc(ans,tmp); if (ans=flow) then exit(ans); if (ds=n) then exit(ans); dec(vddu); if (vddu=0) then ds: inc(du);inc(vddu);exit(ans);function sap(): ans,i,j:vd0:=1 to n-1 do vdi:=1 to n do di: gij:=cij;fij: while (dsn) do inc(ans,dfs(s,maxlongint); exit(ans); readln(n,m,s,t);=1 to m do begin readln(x,y,v); dxi:=x;dyi:=y;inc(cxy,v);inc(cyx,v);=sap();j:useedge:=1 to m do if (fdyidxi=cdyidx
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1