最大流的增广路算法(EK)
来源:互联网 发布:win10精简优化版 编辑:程序博客网 时间:2024/04/29 14:44
首先介绍算法中的一些基本概念:
容量:c(u,v)。表示边 <u,v>最大可以承载的流量。
流量:f(u,v)。表示边 <u,v>中已经有多少流量。
残量:r(u,v)。表示边 <u,v>还可以走多少的流量会达到饱和。r = c – f。
为了理解最大流算法,可以形象的将网络中的各个边联想成水管。那么c和f表示水管内的最大水流量以及水流量。r表示这个水管还能够增加多少单位的水流量。而对于一条路径,其能够增加的最大水流量受限于该路径经过的所有水管中最小的r。
有了这个具象之后,不难理解网络流的三大性质:
1. “水流量”f(u,v)<=”最大水流量”c(u,v)
2. 对于任意一个”水管”,f(u,v) = -f(u,v)。(反对称性)
3. 对于任意一个非源点和宿点的网络结点;流入的水流量一定等于流出的水流量。
要想求出从源点到宿点最大可以流过多少的流量,EK算法的思路很简单,从零流量开始不断地在网络中增加流量,直到没有任意一条从源到宿的路径可以再增加流量为止。而再这个过程中,增加的所有流量和就是可以网络可以承受的最大流。
鉴于以上的分析,总结出EK算法的过程如下:
1. 在网络中求出一条从源到宿的路径。计算该路径能通过的最大流量,记做r’。(求源到宿的路径可以使用BFS)
2. 在网络中将步骤1计算出来的路径流量增加r’,那么每个边的残量r就减少了r’。得到了一个残量网络。(这一步骤称为增广)
3. 在残量网络中重复步骤1,2。直到步骤1不能求出新的路径时,所有r‘的和即为最大流。
假设我们有初始网络如下图:
首先在步骤1中我们得到的路径1->2->3->4。该路径上可以流过的流量为2。得到残量网络如下,图中边上的二元组表示(f,c):
图中有一些奇怪的橙色边,在原始网络中是没有的。这些边称为反向弧。以1->2的反向弧为例,其r = c – f = 0 – (-2) = 2。
那么为什么要设立这些反向弧呢?这个残量网络中,如果只有正向的弧,我们不难发现,已经无法增广了。但是从原始网络中,从肉眼都可以看出最大流为3。如果不继续增广,结果显然不对。
但是在增加了反向弧之后,尚有一条增广路1->3->2->4,流量为1。
首先,在引入反向弧之后,它还是满足网络流的三大性质的,因此,是一个合法的网络流。其次,两个流1->2->3->4和1->3->2->4,相加之后可以理解为整个网络在2->3边上走了一个单位流量。
EK算法在得到一条增广路之后,求残量网络都是以路径能够承受的最大流量去算的。而这个最大的流量配出去之后不一定就是对的。那么反向弧的设立为之前配错的流量提供了一个可以反悔的机会。
EK算法编码如下:
#-*- coding: utf-8 -*-topo = { 1 : {2 : 2, 3 : 1}, 2 : {1 : 0, 3 : 2, 4 : 2}, 3 : {1 : 0, 2 : 0, 4 : 2}, 4 : {2 : 0, 3 : 0} }INF = 0xFFFFFFFFdef ek_bfs(s, t): flag = [0 for i in range(len(topo) + 1)] return ek_bfs_core(flag, s, t, INF)def ek_bfs_core(flag, s, t, r): flag[s] = 1 if s == t: return r for node, cap in topo[s].items(): if flag[node] == 0 and cap > 0: new_r = ek_bfs_core(flag, node, t, min(r, cap)) if new_r != 0: topo[s][node] -= new_r topo[node][s] += new_r return new_r return 0def ek(s, t): total_f = 0 while True: f = ek_bfs(s, t) if f == 0: break total_f = total_f + f return total_fif __name__ == '__main__': print ek(1, 4)
执行可得,结果为3。
- 最大流的增广路算法(EK)
- 最大流(增广路-EK)poj1273
- 最大流的算法(EK算法)—>Edmonds-Karp算法(最短路径增广算法)
- Flow Problem 最大流 最小增广路 SAP算法 从EK算法的753MS降到了46MS
- HDU 3549 Flow Problem 最大流 最小增广路 EK算法 传说中的入门算法
- 最大流算法之EK(最短路径增广算法)
- 网络最大流增广路模板(EK & Dinic)
- poj 1273 最大流EK增广路模板
- 最大流的增广路算法比较
- 网络流最大流问题-1(增广路——EK)
- HDU 3549 Flow Problem 最大流 最小增广路 SAP算法 从EK算法的753MS降到了46MS
- 最大流增广路算法
- POJ 3436-ACM Computer Factory(EK增广路算法)
- 网络流增广路Edmonds-Karp算法(EK算法)代码实现
- poj 3436 最大流的增广路算法
- 最大流EK算法
- 最大流EK算法
- 最大流-EK算法
- 数位DP与记忆化搜索-HDU3652
- Maven-Maven集成的tomcat7插件
- Docker:入门基础
- LeetCode算法题目:Trapping Rain Water
- 关于iOS多线程
- 最大流的增广路算法(EK)
- codeforces round 309 div1 Nudist Beach 二分+搜索
- 建立一个单向链表
- POJ
- WIN 10 安装 ubuntu 双系统
- 静态编译parted3.2
- Ubuntu16.04.2_64_LTS配置LAMP
- centos 安装redis和php redis扩展
- JavaScript中的块级作用域和私有变量