最大流EK算法
给定一个有向图G=(V,E),把图中的边看作
管道,每条边上有一个权值,表示该管道
的流量上限。给定源点s和汇点t,现在假设
在s处有一个水源,t处有一个蓄水池,问从
s到t的最大水流量是多少?

网络流图里,源点流出的量,等于汇点流
入的量,除源汇外的任何点,其流入量之
和等于流出两之和。
下面我们来考虑如何求最大流。
首先,假如所有边上的流量都没有超过容量(水管),那么就把这个流,称为一个可行流。易见,任一网络中都有一个零流,即每弧a上f(a)=0的流f.
我们就从这个零流开始考虑,假如有这么一条路,这条路从源点开始一直一段一段的连到了汇点(这条路叫做可行路径),并且,这条路上的每一段都满足流量<容量,注意,是严格的<,而不是<=。那么,我们一定能找到这条路上的每一段的(容量-流量)的值当中的最小值delta。我们把这条路上每一段的流量都加上这个delta,一定可以保证这个流依然是可行流,这是显然的。
这样我们就得到了一个更大的流,他的流量是之前的流量+delta,而这条路就叫做增广路。我们不断地从起点开始寻找增广路,每次都对其进行增广,直到源点和汇点不连通,也就是找不到增广路为止。当找不到增广路的时候,当前的流量就是最大流。但这个想法是否正确?

考虑上面这样的图,如果我们沿着s-a-b-t路线走仅能得到一个100的流,实际上此图存在流量为200的流(sat+abt).问题出在过早地认为边a → b上流量不为0,因而“封锁”了流量继续增大的可能。
一种解决方法是在第一次找到增广路之后,在把路上每一段的容量减少delta的同时,也把每一段上的反方向的容量增加delta。即在Dec(c[x,y],delta)的同时,inc(c[y,x],delta)
第一次找到增广路: 
第一次找到增光路添加反向边后得到的新图:

这样我们第二次搜索的时候就可以在新的网络里找到新的路径这是一个取消流的操作也可以看作是两条路径的合并。

第二次搜索又找到了一个流量为100的流,加上第一次搜索得到的流量为100的流,总流量上升到200

再对第二次搜索后的图添加反向边,变成:

在此图上再次进行dfs,已经找不到路径了,所以流量无法再增加,最大流就是200
在找增广路的时候采用广度优先的思想,我们就叫它EdmondsKarp算法。他是Ford&Fulkerson算法的改进。下面以一个题目为例给出代码:
poj1273
题目大意:
现在有m个池塘(从1到m开始编号,1为源点,m为汇点),及n条水渠,给出这n条水渠所连接的池塘和所能流过的水量,求水渠中所能流过的水的最大容量.
输入:
5 4
1 2 40
1 4 20
2 4 20
2 3 30
3 4 10
输出:
50
#include<bits/stdc++.h>
using namespace std;
const int maxn=205;
const int inf=0x7fffffff;
int r[maxn][maxn]; //残留网络,初始化为原图
bool visit[maxn];
int pre[maxn];
int m,n;
bool bfs(int s,int t) //寻找一条从s到t的增广路,若找到返回true
{
int p;
queue<int > q;
memset(pre,-1,sizeof(pre));
memset(visit,false,sizeof(visit));
pre[s]=s;
visit[s]=true;
q.push(s);
while(!q.empty())
{
p=q.front();
q.pop();
for(int i=1;i<=n;i++)
{
if(r[p][i]>0&&!visit[i])
{
pre[i]=p;
visit[i]=true;
if(i==t) return true;
q.push(i);
}
}
}
return false;
}
int EdmondsKarp(int s,int t)
{
int flow=0,d,i;
while(bfs(s,t))
{
d=inf;
for(i=t;i!=s;i=pre[i])
d=d<r[pre[i]][i]? d:r[pre[i]][i];
for(i=t;i!=s;i=pre[i])
{
r[pre[i]][i]-=d;
r[i][pre[i]]+=d;
}
flow+=d;
}
return flow;
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
int u,v,w;
memset(r,0,sizeof(r));///
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
r[u][v]+=w;
}
printf("%d\n",EdmondsKarp(1,n));
}
return 0;
}
最大流EK算法的更多相关文章
- 二分图的最大匹配——最大流EK算法
序: 既然是个图,并且求边数的最大值.那么这就可以转化为网络流的求最大流问题. 只需要将源点与其中一子集的所有节点相连,汇点与另一子集的所有节点相连,将所有弧的流量限制置为1,那么最大流 == 最大匹 ...
- 最大流EK算法/DINIC算法学习
之前一直觉得很难,没学过网络流,毕竟是基础知识现在重新来看. 定义一下网络流问题,就是在一幅有向图中,每条边有两个属性,一个是cap表示容量,一个是flow 表示流过的流量.我们要求解的问题就是从S点 ...
- 最大流——EK算法
一.算法理论 [基本思想] 反复寻找源点s到汇点t之间的增广路径,若有,找出增广路径上每一段[容量-流量]的最小值delta,若无,则结束.在寻找增广路径时,可以用BFS来找,并且更新残留网络的值(涉 ...
- (通俗易懂小白入门)网络流最大流——EK算法
网络流 网络流是模仿水流解决生活中类似问题的一种方法策略,来看这么一个问题,有一个自来水厂S,它要向目标T提供水量,从S出发有不确定数量和方向的水管,它可能直接到达T或者经过更多的节点的中转,目前确定 ...
- vector实现最大流EK算法
序: 在之前的文章中实现了不利用STL实现EK算法,效率也较高.这次我们企图简化代码,减少变量的使用与手写模拟的代码. 注意:vector等STL的container在不开O2优化的时候实现同一个效果 ...
- 最大流EK算法模板
最近学了下最大流算法,大概思想算是懵懵懂懂了,现在想把模板记录下来,以备后面深刻学习之用. #include<cstdio> #include<cstring> using n ...
- POJ-1459(最大流+EK算法)
Power Network POJ-1459 这题值得思索的就是特殊的输入,如何输入一连串字符.这里采用的方法是根据输入已知的输入格式,事先预定好要接受的数据类型. 这里套用的板子也是最大流的模板,但 ...
- 【转】最大流EK算法
转自:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html 图-1 如图-1所示,在这个运输网络中,源点S和汇点T分别是1,7 ...
- POJ1273 最大流 EK算法
套了个EK的模板 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdi ...
随机推荐
- 浅谈DPCHookSSDT和RemoveDPC
最近学了DPC这一对,把Win7 32位和64位都做了,查阅了大量的资料,并且进行了大量调试,理一下思路,为了后面更好的学习. 转载请注明出处:http://www.cnblogs.com/littl ...
- L1-1. 出生年【STL放的位置】
L1-1. 出生年 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 以上是新浪微博中一奇葩贴:“我出生于1988年,直到25岁才 ...
- KeyStore和TrustStore
笔者的这篇文章参考了http://docs.oracle.com/cd/E19509-01/820-3503/ggfgo/index.html KeyStore和TrustStore在很多HTTPS双 ...
- win7快捷键和ubuntu快捷键
http://www.cnblogs.com/xfiver/archive/2010/12/08/1899905.html http://www.pc841.com/article/20121203- ...
- GPP加密破解工具gpp-decrypt
GPP加密破解工具gpp-decrypt GPP是Group Policy Preferences(组策略首选项)的缩写,这是一个组策略实施工具.通过该工具,网络管理员可以实现更多的网络管理,如驱 ...
- sed理论讲解、实战
1.Sed是操作.过滤和转换文本内容的强大工具,常用功能有增删改查.过滤.取行. options(常用参数): -n:使用安静(silent)模式,在一般 sed 的用法中,所有来自 STDIN 的数 ...
- 将压缩包文件(rar/zip)伪装成图片(jpg/gif/png/ico)
1.在Windows上使用copy命令,缺点是只能是jpg文件,gif不支持,命令如下: copy in1.jpg+in2.rar out.jpg 2.网上说使用UEdit方式可以制作gif,但是测试 ...
- 如何直接打开使用locate等查找到的文件
很多的时候需要使用locate去定位文件,找到了文件之后接下来就是使用相应的文本编辑工具如gvim进行打开. 这个时候最烦心的就是去复制一大长串的地址了. 如果能让定位和打开一体操作就最好了,这就需要 ...
- Proftpd快速搭建FTP服务器
前言 在Linux系统中,FTP服务器软件有很多,都已经成熟,像vsftpd, wu-ftp, Pure-FTPd等.但这些软件安装配置起来都比较麻烦,搭建个人的FTP服务器,还是Proftpd比较简 ...
- 解决Gradle执行命令时报Could not determine the dependencies of task ':compileReleaseJava'.
Could not determine the dependencies of task ':compileReleaseJava'. > failed to find target andro ...