- 1、本文档共9页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
网络最大流的算法
网络最大流的算法分类:
一、Ford-Fulkerson增广路方法
1、 Ford-Fulkerson标号算法(最简单的实现)
分别记录这一轮扩展过程中的每个点的前驱与到该节点的增广最大流量,从源点开始扩展,每次选择一个点(必须保证已经扩展到这个点),检查与它连接的所有边,并进行扩展,直到扩展到t。
2、最大容量增广路算法
每次找一条容量最大的增广路来增广,找的过程类似Dijkstra,实现起来相当简单。
3、Edmonds-Karp,最短路增广算法的BFS实现
每次找一条最短的增广路,BFS是一个可以很方便的实现思想。
4、距离标号算法
最短路增广的O(n)寻找实现,使用距离函数d:d[t]=0;d=d[j]+1若存在(i,j)∈E;只有路径上满足d=d[i+1]+1的增广路才为满足要求的,一开始我们初始化使标号恰好满足要求,之后不断更改标号使其可以使增广继续。
5、Dinic,分层思想
对网络分层(按照距t的距离),保留相邻层之间的边,然后运用一次类似于距离标号的方法(其实质是DFS)进行增广。
二、预留与推进算法
1、一般性算法
随便找个点,要么将他的盈余推出去,要么对他进行重标记,直至无活跃点为止。
2、重标记与前移算法
维护一个队列,对一个点不断进行推进与重标记操作,直至其盈余为0,若过程中他没有被重标记过,则可出列,否则加入队头,继续等待检查。
3、最高标号预留与推进算法
记录d值,然后优先处理d值较高的,直至没有盈余。
网络最大流的算法实现
一、Edmonds-Karp(EK)算法就是用广度优先搜索来实现Ford-Fulkerson方法中对增广路径的计算,时间复杂度为O(VE2)Shortest Augmenting Path
{ x -- 0
while 在残量网络 Gx 中存在增广路 s ~ t do
{ 找一条最短的增广路径 P
delta -- min{rij:(i,j) 属于 P}
沿 P 增广 delta 大小的流量
更新残量网络 Gx
}
return x
}
在无权边的有向图中寻找最短路,最简单的方法就是广度优先搜索 (BFS),E-K 算法就直接来源于此。每次用一遍 BFS 寻找从源点 s 到终点 t 的最短路作为增广路径,然后增广流量 f 并修改残量网络,直到不存在新的增广路径。
E-K 算法的时间复杂度为 O(V*E^2),由于 BFS 要搜索全部小于最短距离的分支路径之后才能找到终点,因此可以想象频繁的 BFS 效率是比较低的。实践中此算法使用的机会较少。代码如下:
#define VMAX 201
int n, m; //分别表示图的边数和顶点数
int c[VMAX][VMAX]; //容量
int Edmonds_Karp( int s, int t ) //输入源点和汇点
{ int p, q, queue[VMAX], u, v, pre[VMAX], flow= 0, aug;
while(true)
{ memset(pre,-1,sizeof(pre)); //记录父节点
for( queue[p=q=0]=s; p=q; p++ ) //广度优先搜索
{ u= queue[p];
for( v=0; vmpre[t]0; v++ )
if( c[u][v]0 pre[v]0 ) pre[v]=u, queue[++q]=v;
if( pre[t]=0 ) break;
}
if( pre[t]0 ) break; //不存在增广路
aug= 0x7fff; //记录最小残留容量
for( u=pre[v=t]; v!=s; v=u,u=pre[u] )
if(c[u][v]aug) aug=c[u][v];
for( u=pre[v=t]; v!=s; v=u,u=pre[u] )
c[u][v]-=aug, c[v][u]+=aug;
flow+= aug;
}
return flow; }//0 至 n-1
二、Ford-Fulkerson方法
每次找增广路,把这条路上的所有点的流量加上这条路上的残余容量,再找新的增广路,直到找不
文档评论(0)