10-最大流问题解析
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Dinic算法
• Dinic算法的基本思路是分阶段地在层次图中改进流量。层 次图是在残留网络的基础上对每个节点加一个层次标记 level,标出该节点到源点的距离。显然,源点的level为0。
• 由节点的层次引出了层次图D3=(V3,E3)的概念:对于 残留网络D2=(V2,E2)中的一条边(u,v),当且仅当 level(u)+1=level(v)时,边(u,v)∈E3;V3={v|E3中 边与u相连}。也就是说,在程序实现的时候,层次图并 不是构建出来的,而是对每个节点标记层次,扩展可增广 路径时只需判断边(u,v)是否满足约束条件level(u) +1=level(v)即可。
function dfs(v,a:longint):longint; var ans,flow,tmp,u,value:longint; begin if (v=vt) or (a=0) then exit(a); ans:=0; tmp:=h[v]; while tmp<>-1 do begin u:=g[tmp].y; value:=g[tmp].r; if (level[u]=level[v]+1) then begin flow:=dfs(u,min(a,value)); if flow<>0 then begin g[tmp].r:=g[tmp].r-flow; g[g[tmp].op].r:=g[g[tmp].op].r+flow; ans:=ans+flow; a:=a-flow; if a=0 then break; end; end; tmp:=g[tmp].next; end; exit(ans); end;
Dinic递归版
program maxflow_Dinic; type edge=record y,r,next,op:longint; end; var g:array[1..400] of edge; level,q,h:array[1..200] of longint; n,m,i,ans,a,b,c,tot,vs,vt:longint;
可增广路径的定义
• 设F是一个可行流,p是从s到t的一条路,若p满足下述两个 条件,则称p是关于可行流F的一条可增广路径,亦称可改 进路径: • 在p+的所有前向弧(u,v)上,0<=f(u,v)<C(u,v)。 • 在p-的所有后向弧(u,v)上,0<f(u,v)<=C(u,v)。
增广路径SACBDET
procedure add(a,b,c:longint); begin inc(tot); g[tot].y:=b; g[tot].r:=c; g[tot].next:=h[a]; h[a]:=tot; g[tot].op:=tot+1; inc(tot); g[tot].y:=a; g[tot].r:=0; g[tot].next:=h[b]; h[b]:=tot; g[tot].op:=tot-1; end;
基于最大流定理上的最大流算法
• 如果残留网络上找不到可增广路径,则当前流为最大流; 反之,如果当前流不为最大流,则残留网络上一定有可增 广路径。
初始化一个可行流:对所有u,v∈V f(u,v)←0 现有网络流的残留网络上有增广路径吗?
按上面方法对增广路径进行改进
F为最大流
• 计算最大流的关键在于怎样找出可增广路经。寻找一条可 增广路径的常用方法有3种:DFS,BFS,标号搜索(PFS)
• 流的容量限制:对于每条弧(u,v)∈E来说,弧流量为一个不大于弧容量的 非负数,即0<=f(u,v)<=C(u,v)。 • 流的平衡条件:除源点和汇点外的任意中间点u,流入u的“流量”与流出u 的“流量”相等。
(3)网络的流量V(F):指源点的净流出流量和汇点的净流入流量。
寻找网络G上可能的最大流量即为网络G上的最大流问题
Dinic算法的基本流程
初始化网络流图 根据残留网络计算层次图 汇点不在层次图内
否 是
在层次图内用一次DFS过程改进流量
算法结束
由流程图可以看出,算法呈循环结构。每一次循环为一个阶段。在 每个阶段中,首先根据残留网络建立层次图(一般采用BFS算法建立层次 图),然后用DFS过程在层次图内扩展可增广路径,调整流量。增广完毕 后,进入下一个阶段。这样不断重复,直到汇点不在层次图内出现为止。 汇点不在层次图内意味着残留网络中不存在从源点到汇点的路径,即没有 可增广路径。对于有n个节点的网络流图,Dinic算法最多有n个阶段。
function bfs:boolean; var i,f,r,tmp,v,u:longint; begin fillchar(level,sizeof(level),0); f:=1; r:=1; q[f]:=vs; level[vs]:=1; repeat v:=q[f]; tmp:=h[v]; while tmp<>-1 do begin u:=g[tmp].y; if (g[tmp].r<>0) and (level[u]=0) then begin level[u]:=level[v]+1; inc(r); q[r]:=u; if u=vt then exit(true); end; tmp:=g[tmp].next; end; inc(f); until f>r; exit(false); end;
最大流问题
• 在一个单源单汇的简单有向图引入流量因素,且要求计算 满足流量限制和平衡条件的最大可行流时,就产生了最大 流问题。
基本概念
(1)网络的定义:设D是一个简单有向图D=(V,E)。在V中指定了一个源点 (记为Vs)和一个汇点(记为Vt),对于每一条弧(Vi,Vj)∈E,对应有 一个Cij>=0,称为弧的容量。也记为D=(V,E,C)。 (2)网络的可行流F。满足下述条件的流F称为网络的可行流。
在可增广路径p上改进流量
•
残留网络
• 按照上述方法对弧进行分类,初始流图中的每条弧既有容 量又有前向弧流量和后向弧流量,因此不够简洁,不方便 寻找可增广路径。 • 所谓残留网络,就是将初始流图上的前向弧的容量调整为 “剩余容量”=C(u,v)-f(u,v);后向弧的容量调整为“可退流 量”=f(v,u);去除“剩余流量”为0的弧。在这样的图上找 可增广路经变得更加容易。
在可增广路径的基础上计算最大流
• 最大流算法的核心是计算可增广路径
可增广路径的基本概念
• 退流的概Βιβλιοθήκη Baidu和弧的分类
• 若p是网络中连接源点s和汇点t的一条路,且路的方向是从 s到t的,则路上的弧有前向弧和后向弧两种。 • 前向弧:弧的方向与路的方向一致。前向弧的全体记为p+ • 后向弧:弧的方向与路的方向相反。后向弧的全体记为p-