给定一个有向图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算法的更多相关文章

  1. 二分图的最大匹配——最大流EK算法

    序: 既然是个图,并且求边数的最大值.那么这就可以转化为网络流的求最大流问题. 只需要将源点与其中一子集的所有节点相连,汇点与另一子集的所有节点相连,将所有弧的流量限制置为1,那么最大流 == 最大匹 ...

  2. 最大流EK算法/DINIC算法学习

    之前一直觉得很难,没学过网络流,毕竟是基础知识现在重新来看. 定义一下网络流问题,就是在一幅有向图中,每条边有两个属性,一个是cap表示容量,一个是flow 表示流过的流量.我们要求解的问题就是从S点 ...

  3. 最大流——EK算法

    一.算法理论 [基本思想] 反复寻找源点s到汇点t之间的增广路径,若有,找出增广路径上每一段[容量-流量]的最小值delta,若无,则结束.在寻找增广路径时,可以用BFS来找,并且更新残留网络的值(涉 ...

  4. (通俗易懂小白入门)网络流最大流——EK算法

    网络流 网络流是模仿水流解决生活中类似问题的一种方法策略,来看这么一个问题,有一个自来水厂S,它要向目标T提供水量,从S出发有不确定数量和方向的水管,它可能直接到达T或者经过更多的节点的中转,目前确定 ...

  5. vector实现最大流EK算法

    序: 在之前的文章中实现了不利用STL实现EK算法,效率也较高.这次我们企图简化代码,减少变量的使用与手写模拟的代码. 注意:vector等STL的container在不开O2优化的时候实现同一个效果 ...

  6. 最大流EK算法模板

    最近学了下最大流算法,大概思想算是懵懵懂懂了,现在想把模板记录下来,以备后面深刻学习之用. #include<cstdio> #include<cstring> using n ...

  7. POJ-1459(最大流+EK算法)

    Power Network POJ-1459 这题值得思索的就是特殊的输入,如何输入一连串字符.这里采用的方法是根据输入已知的输入格式,事先预定好要接受的数据类型. 这里套用的板子也是最大流的模板,但 ...

  8. 【转】最大流EK算法

    转自:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html 图-1 如图-1所示,在这个运输网络中,源点S和汇点T分别是1,7 ...

  9. POJ1273 最大流 EK算法

    套了个EK的模板 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <stdi ...

随机推荐

  1. Manajro17配置

    :Manjaro近来点击率一直排行第一,比较适合笔记本使用,这次从下载刻录开始讲述: 1: 下载刻录 因为一些环境特殊原因,官网下载还是比较慢的,普通用户还是从清华镜像源下载比较快,当然你也可以选择官 ...

  2. tomcat7.0.55配置单向和双向HTTPS连接(二)

    上一篇文章:tomcat7.0.55配置单向和双向HTTPS连接 只是简要的配置了一下HTTPS,还有许多问题没有解决,本篇来解决这些文件 首先按照这篇文章:Widows下利用OpenSSL生成证书来 ...

  3. [Bzoj3687]简单题(bitset)

    3687: 简单题 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1150  Solved: 565[Submit][Status][Discuss] ...

  4. Netty学习_Netty框架入门教程:Netty入门之HelloWorld实现

    我们可能都学过Socket通信/io/nio/aio等的编程.如果想把Socket真正的用于实际工作中去,那么还需要不断的完善.扩展和优化.比如很经典的Tcp读包写包问题,或者是数据接收的大小,实际的 ...

  5. systemtap-oracle

    https://savvinov.com/2015/12/21/non-intrusive-tracing/ https://mahmoudhatem.wordpress.com/2016/01/11 ...

  6. windows10 安装 mysql 5.6 教程

    首先是下载 mysql-installer-community-5.6.14.0.msi ,大家可以到 mysql 官方网去下载. win10的安全机制比较严格,安装前最好到<设置>--& ...

  7. xshell登陆腾讯云服务器

    2016-12-11   00:17:36 前段时间在同学的介绍下关注了一下腾讯云:然后里面有学生优惠可以拿到免费的域名和云服务器.所以感兴趣就实验了一下,今天中午抢到了“1元特惠的学生包”,里面有免 ...

  8. C++ 面试问题

    一面 (1) 多态性都有哪些?(静态和动态,然后分别叙述了一下虚函数和函数重载) (2) 动态绑定怎么实现?(就是问了一下基类与派生类指针和引用的转换问题) (3) 类型转换有哪些?(四种类型转换,分 ...

  9. mac异常删除管理员账户恢复操作

    重新启动电脑,同时按下command+s键进入命令行方式 待系统加载完成后顺序输入以下命令: /sbin/mount -uaw rm var/db/.applesetupdone reboot 待系统 ...

  10. 解决Gradle执行命令时报Could not determine the dependencies of task &#39;:compileReleaseJava&#39;.

    Could not determine the dependencies of task ':compileReleaseJava'. > failed to find target andro ...