原题链接

poj 1273

问题

图论中有一个重要问题,假设有一个水管网图,每根水管都规定了一个可以流的方向,从v号结点到u号结点最大允许通过的水量为c(v,u),有一个源点s存储了无限多的水,有一个汇点可以存储无限多的水。问:从源点流向汇点的水流的最大速率是多少?

思路

采用经典的EK算法,时间复杂度为O(n*m^2)n为结点数,m为边数,虽然上界很高,但是一般情况很能到上界,一般的情况要好的多。

四个概念,一个定理:

网络流的概念和定理非常多,为了不混淆,先只讲两个会用到的定理。
1.反向边:
这个概念很好理解,对于图中的每一条有向边,如果存在一条方向相反的边,这条边就是反向边。
2.可行流:
从s流向t的任意一个满足条件的流(不一定是最大流)。

3.残留网络:
在图中找到任意一条可行流,并将该可行流的路径上的每一条边都建立一个反向边。 反向边的权值是可行流的权值,然后将正向边的权值更新为原来的权值-可行流的权值。

4.增广路径:
在当前的图中,存在一条从s到t的可行流路径。

定理1:
如果f是最大流,GfG_fGf​中一定不存在增广路径。
证明:
因为f可行流+f增广路径=f可行流f_{可行流}+f_{增广路径}=f_{可行流}f可行流​+f增广路径​=f可行流​
如果f是最大流,要满足上式,f增广路径=0f_{增广路径}=0f增广路径​=0,所以不存在增广路径。

FF思想

这是一种找最大流的思想,但是他有很多中算法实现。
1.找到一条从s到t的可行流路径。
2.记录可行流的大小。
2.根据可行流路径建立增广网络。
3.重复上述1到3,直到没有增广路径。

FF思想有很多严格的证明方法,我这里采用最直观但是相对没那么严谨的方法。
假设s到t有两条最大流,分别如下。
但是在寻找最大流时,我们的运气不好,本来应该经过A点到达t点,但是却在A点进行了拐弯,从下面到达了t点。按理来说这样的话,下面的最大流我们永远也无法找到了。但是,我们有在找到一条可行流时,会建立反向边,所以,这时候s到B时,还可以往上走,抵消掉了A->B的水流,从而到达了t点。所以,这个算法可以找到最大流。

EK算法

EK算法,包括dinic算法都是基于FF思想的一种算法。是FF思想的具体实现,但是,EK算法是最简答的一种算法。
1.bfs遍历图,找到一条可行流,累加可行流。
2.更新残余网络。
3.判断是否存在增广路,如果存在,重复1,2。
4.输出累加的可行流,即最大流。原理参考f可行流+f增广路径=f可行流f_{可行流}+f_{增广路径}=f_{可行流}f可行流​+f增广路径​=f可行流​

代码:

#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#define debug(x) cout<<x<<endl;using namespace std;typedef long long LL;const int N = 205, M = 205, INF = 0x3f3f3f3f;LL G[N][M];//图
LL flow[N], pre[N];//结点的流,前驱
int n, m;//结点数,边数
int bfs(int s,int t) {memset(pre, -1, sizeof pre);memset(flow, 0, sizeof flow);queue<int > q;flow[1] = INF;//代表最多可以流出的水量q.push(s);while (q.size()) {int v = q.front(); q.pop();for (int i = 1; i <= n; i++) {if (G[v][i] > 0&&pre[i]==-1) {q.push(i);pre[i] = v;flow[i] = min(flow[v],G[v][i]);}}if (v == t) break;}return flow[t];
}LL EK(int s, int t) {LL tol = 0;LL  res;//存放流入汇点的数值while (1){//存在增广路res = bfs(s, t);if (res == 0)break;int p = t;while (p != s) {//更改残留图G[pre[p]][p] -= res;G[p][pre[p]] = res;//回流p = pre[p];}tol += flow[t];}return tol;
}int main() {while (~scanf("%d%d", &m, &n)) {memset(G, 0, sizeof G);for (int i = 0; i < m; i++) {int a, b, c;scanf("%d%d%d", &a, &b, &c);G[a][b] += c;}printf("%lld\n", EK(1, n));}return 0;
}/*
test1:
7 6
1 2 40
1 4 30
2 3 30
2 5 30
4 5 40
3 6 40
5 6 5070test2:
7 6
1 2 5
1 4 6
2 3 4
4 5 4
2 5 2
3 6 3
5 6 79
test 3
1 2
1 2 10
*/

最大流_FF思想_EK算法相关推荐

  1. 最大流网络之Push-Relabel算法

    上一篇文章介绍了网络最大流中的Ford-Forkerson算法和它的改进版本.对于解决网络最大流.最小割相关问题,今天我们来看一个效率更快的算法Push-Relabel算法. 1.Push-Relab ...

  2. 求解最大流的四种算法介绍、利用最大流模型解题入门

    求解最大流的四种算法介绍.利用最大流模型解题入门 上一篇中介绍了网络流的基础,最大流最小割定理的证明,下面来看如何求一个容量网络的最大流,这里介绍四种算法:EK算法.SAP算法.DINIC算法.HLP ...

  3. 最大流EK和Dinic算法

    最大流EK和Dinic算法 EK算法 最朴素的求最大流的算法. 做法:不停的寻找增广路,直到找不到为止 代码如下: @Frosero #include <cstdio> #include ...

  4. Java Jvm 中的垃圾回收机制中的思想与算法 《对Java的分析总结》-四

    Java中的垃圾回收机制中的思想与算法 <对Java的分析总结>-四 垃圾回收机制 中的思想与算法 引用计算法 给对象中添加一个引用计数器,每当一个地方引用它的时候就将计数器加1,当引用失 ...

  5. 一种面向业务流的内存管理算法

    在象通讯系统中的基站这样的复杂嵌入式系统中,对于内存管理模块的效率具有很高的要求,因此内存管理模块的算法很有讲究.讲究在于,不仅要考虑算法的效率,还要兼顾算法是否会带来大量的内存碎片以及如何进行内存碎 ...

  6. 函数式接口和Stream流式思想

    函数式接口和Stream 1. 函数式接口 1.1 函数式接口概述 利用接口操作语法格式,对于方法的声明作出二次封装!!!方法声明:权限修饰符 是否静态 返回值类型 方法名(形式参数列表);对于接口而 ...

  7. Sentinel限流及其滑动窗口算法

    Sentinel限流及其滑动窗口算法 Sentinel的限流原理 滑动时间窗口算法 Sentinel的限流原理 限流效果,对应有DefaultController快速失败 WarmUpControll ...

  8. 网络流之最大流 EK/Dinic/Isap算法 学习笔记

    EK 算法流程 不停地找增广路进行增广,知道找不到增广路为止. 每一次bfs只找一条增广路. 时间复杂度O(VE2)O(VE^2) 代码 // codevs 1993 #include<iost ...

  9. 赠书|零压力入门算法的顶流畅销书《漫画算法》

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来,认为算法高深莫测.难以掌握的同学请起立. 好了好了, ...

最新文章

  1. 斯坦福被炮轰:用算法分配5000支新冠疫苗,医护人员只有7支
  2. $this-load-view()
  3. linux 新建用户配置文件 /etc/login.defs 简介
  4. sharepoint2010网站根据权限隐藏ribbon
  5. Scrapy 1.4 文档 01 初窥 Scrapy
  6. appium+java(五)微信小程序自动化测试实践
  7. VUE 学习代码 监视和 模板语法回调函数
  8. 《JavaScript 模式》读书笔记
  9. 好用的换ip工具分享
  10. Photoshop技巧
  11. MATLA雾霾下的交通标志识别系统[GUI界面]
  12. 计算机win10+上锁,win10系统给电脑屏幕上锁的操作方法
  13. 解决外边距坍塌的几种方法
  14. Linux 网桥配置br-lan、eth0、eth1、ra0、rai0
  15. 非常全面的数字人解决方案(含源码)
  16. “AI+停车”数百亿的市场等你来加入
  17. SQLSERVER完全优化教程
  18. Eclipse红叉报错
  19. esp8266驱动四脚oled显示文字和图片
  20. 05 TypeScript 类的使用

热门文章

  1. 小敏利用计算机设计了一个计算程序,七年级上期中练习卷2013-2014第一学期定稿(10页)-原创力文档...
  2. 各种搞怪的标点符号表情
  3. 初识React及React开发依赖介绍
  4. 三个等号和二个等号的区别是
  5. Site Template
  6. Templates基础
  7. 利用 Github Pages 和 Hugo 快速搭建免费的个人网站
  8. java——接口作为方法的参数和返回值
  9. 腾讯广告算法大赛2020-广告产品种类单特征-入门级
  10. VC890D老款数字万用表内部旋钮触点