【转】最大流EK算法

转自:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html

图-1

如图-1所示,在这个运输网络中,源点S和汇点T分别是1,7,各边的容量为C(u,v)。图中红色虚线所示就是一个可行流。标准图示法如图-2所示:

其中p(u,v) / c(u,v)分别表示该边的实际流量与最大容量。

关于最大流

熟悉了什么是网络流,最大流也就很好理解了。就是对于任意的u∈V-{s},使得p(s,u)的和达到最大。上面的运输网络中,最大流如图-3所示:MaxFlow=p(1,2)+p(1,3)=2+1=3。

在介绍最大流问题之前,先介绍几个概念:残余网络,增广路径,反向弧,最大流定理以及求最大流的Ford-Fulkerson方法。

残余网络 增广路径 反向弧

  观察下图-4,这种状态下它的残余网络如图-5所示:

也许现在你已经知道什么是残余网络了,对于已经找到一条从S 到T的路径的网络中,只要在这条路径上,把C(u,v)的值更新为C(u,v)-P(u,v),并且添加反向弧C(v,u)。对应的增广路径Path为残留网络上从S到T的一条简单路径。图-4中1,2,4,7就是一条增广路径,当然还有1,3,4,7。

此外在未做任何操作之前,原始的有向图也是一个残余网络,它仅仅是未做任何更新而已。

最大流定理

如果残留网络上找不到增广路径,则当前流为最大流;反之,如果当前流不为最大流,则一定有增广路径。

Ford-Fulkerson方法

介绍完上面的概念之后,便可以用Ford-Fulkerson方法求最大流了。为什么叫Ford-Fulkerson方法而不是算法,原因在于可以用多种方式实现这一方法,方式并不唯一。下面介绍一种基于广度优先搜索(BFS)来计算增广路径P的算法:Edmonds-Karp算法。

算法流程如下:

设队列Q:存储当前未访问的节点,队首节点出队后,成为已检查的标点;

Path数组:存储当前已访问过的节点的增广路径;

Flow数组:存储一次BFS遍历之后流的可改进量;

Repeat:

Path清空;

源点S进入Path和Q,Path[S]<-0,Flow[S]<-+∞;

While Q非空 and 汇点T未访问 do

Begin

队首顶点u出对;

For每一条从u出发的弧(u,v) do

If v未访问 and 弧(u,v) 的流量可改进;

Then Flow[v]<-min(Flow[u],c[u][v]) and v入队 and Path[v]<-u;

End while

If(汇点T已访问)

Then 从汇点T沿着Path构造残余网络;

Until 汇点T未被访问

时间: 2024-10-10 02:54:15

【转】最大流EK算法的相关文章

HDU 3549 Flow Problem ( 最大流 -EK 算法)

C++,G++的读取速度差距也太大了 Flow Problem 题意:n,m表示n个点m条有向带权边 问:从1-n最大流多少 裸最大流,拿来练手,挺不错的 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> const int N = 210; #define

POJ1273 最大流 EK算法

套了个EK的模板 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdio.h> #include <iostream> #include <climits> #include <cstring> #include <cmath> #include <stack> #include <queue> #i

图论 最大流EK算法

今天接触了最大流,网上有很多ppt,耐心看下,再敲几遍代码大概就能懂意思了 EK 算法 关键是要理解要理解反悔的这个意思,因为每次当你选择了一种方式,但是这种方式不一定是最优的所以我们要再来建立一条反向边, 来完成反悔的策略 然后就是大概一直找增广路,改变最大的值,一直到找不到增广路为止 现在把模板的代码附上,并且给予注释 下面有两种方式一种是紫书上刘汝佳的代码,还有种是用链式前向星,还有种是dfs的方式,之后会继续补充 分别给出两种代码 struct Edge{ int from,to,cap

【转】网络最大流——EK算法详解

原文  http://blog.csdn.net/a1dark/article/details/11177907 EdmondsKarp算法,简称EK算法,O(m^2n) 因为是初学教程,所以我会尽量避免繁杂的数学公式和证明.也尽量给出了较为完整的代码.本文的目标群体是网络流的初学者,尤其是看了各种NB的教程也没看懂怎么求最大流的小盆友们.本文的目的是,解释基本的网络流模型,最基础的最大流求法,即bfs找增广路法,也就是EK法,全名是Edmond-Karp,其实我倒是觉得记一下算法的全名和来历可

最大流 EK算法 (转)

反复寻找源点s到汇点t之间的增广路径,若有,找出增广路径上每一段[容量-流量]的最小值delta,若无,则结束. 在寻找增广路径时,可以用BFS来找,并且更新残留网络的值(涉及到反向边). 而找到delta后,则使最大流值加上delta,更新为当前的最大流值. (粗体表明需要掌握的概念) 关于反向边: 以下摘至HDOJ的课件和网上的: 首先来看一下基本的网络流最大流模型. 有n个点,有m条有向边,有一个点很特殊,只出不进,叫做源点,通常规定为1号点.另一个点也很特殊,只进不出,叫做汇点,通常规定

最大流EK算法模板

最近学了下最大流算法,大概思想算是懵懵懂懂了,现在想把模板记录下来,以备后面深刻学习之用. 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 5 #define _clr(x, y) memset(x, y, sizeof (x)) 6 #define Min(x, y) (x < y ? x : y) 7 #define INF 0x3f3f3f3f 8 #define N 210 9 10 in

最大流——EK算法

一.算法理论 [基本思想] 在网络中找增广路径,找到一条增广路径就计算这条路径可已通过的最大流,即瓶颈边的容量.然后修改这条路径上的每条边的容量,如果在路径上就减去刚求出来的流量加上流量其他的边的容量不变.然后在这个残留网路上在搜一条增广路径,直到没有增广路径为止. 一直找增广路径(BFS),假如有,记录增广路的最小值k,ans +=k ,并更新网络的值(要用反向边). [算法详解] 点击

排涝 网络流--最大流 ek算法

传送门: 以前没接触过最大流问题,刚开始以为是用kruscal算法求最小生成树呢,并且题上也是显示最小树的专题: 反正还行吧,捣鼓了两天,总算稍微理解了一下,等会回来整理一下知识点. 1 #include <iostream> 2 #include <queue> 3 #include <algorithm> 4 #include <cstring> 5 #include <cstdio> 6 using namespace std; 7 con

HDU 1532 Drainage Ditches(最大流 EK算法)

题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1532 思路: 网络流最大流的入门题,直接套模板即可~ 注意坑点是:有重边!!读数据的时候要用"+="替换"=". 对网络流不熟悉的,给一篇讲解:http://www.cnblogs.com/ZJUT-jiangnan/p/3632525.html. ?(? ? ??)我是看这篇博客才入门的. 代码: 1 #include <cstdio> 2 #includ