catalog

  • 最大流算法
    • 错误点
    • 错误点
  • 残留网络的 可叠加性
  • 流网络的 点和边
  • 最小割定理证明
    • version_0
    • version_1

最大流算法

错误点

for( int i = 0; i < n; ++i){int a, b, w;cin >> a >> b >> w;Add_a_edge( a, b, w);
}

很容易忘记添加 (反向边)!!! Add_a_edge( b, a, 0)

最好, 你另外写一个Add_flowEdge( a, b, w)封装一下, 然后在他里面, 直接添加2条边!!

错误点

//* 最大流算法模板int max_flow( int _cur, int _flow_in){if( _cur == End){ return _flow_in;}int flow_out = 0;for( int nex, i = Head_start[ _cur]; ~i; i = Nex[ i]){nex = Ver[ i];if( LayerGraph_depth[ nex] != LayerGraph_depth[ _cur] + 1|| Wth[ i] <= 0){ Head_start[ _cur] = Nex[ i];continue;}int flowed = max_flow( nex, min( Wth[ i], _flow_in - flow_out));//{ effectflow_out += flowed;Wth[ i] -= flowed;Wth[ i ^ 1] += flowed;//}if( flow_out >= _flow_in){LayerGraph_depth[ _cur] = -1;    //< @Mark_0return _flow_in;}}//* now, flow_out < flow_inif( flow_out == 0){ //< @Mark_1LayerGraph_depth[ _cur] = -1;}return flow_out;
}
  • @Mark_0: 必须要注释掉!!!
    他对应的情况是: (流入flow_in的少) (可供流出flow_out的多), 此时, 该点 本次流完后, 该点cur 还可以继续流出去!!!
    但是, 你确认为 该点不能再流出去了!!! 你错会意! 这个点, 并没有榨干!!!
    如果不注释掉 (即把_cur点 给删掉), 就说明: _cur本来是还可以往End流入流量的, 但是, 你却把他给删掉了;
    如果不注释, 是会(超时)的!!!
  • @Mark_1: 应该注释掉
    不管flow_out是多少, 只要能 (出for循环), 即意味着: (流入flow_in的多) (可以流出flow_out的少)
    即, 能流出去的 全流出去了, 但却还不够, 即, 已经榨干了!!! (正好和上面的情况, 相反), 此时, 这个cur点, 就可以删除了, 他已经榨干了

残留网络的 可叠加性

比如说: 你在二分 [0, 1, 2, ...., n], 每一个数 都对应一个图, 对该图求最大流, 如果用二分, 则比较耗时 因为每次二分, 都是在建立一个全新图!!! 这很耗时
但如果说, [0, 1, 2, 3, ..., n] 对应的图, 是动态增长的 即: (i)点的图 是在(i-1)图的基础上, 新加入一些点 和 边
此时, 不用二分, 有更好的办法


即: 给定你一个 "动态增长"的图, 则这个图存在叠加性 (每次的叠加, 都是在原图的基础上, 新加入一些点 和 边)

即, 图Pre -> (加上一些新的点和边 {也可以说是一个图}) -> 图Cur

对应的, 图Pre的残留网络restPre -> (加上一些新的点和边 (称为: restAdd}) -> 图Cur的残留网络restCur

假如说, 我们现在已经知道了: 图Pre 的 最大流, 如何去求图Cur 的 最大流呢??
(所谓的: 知道 图Pre的最大流, 意味着: 我们现在有一个 restPre_ans的 残留网络. 注意, restPre_ans 是 restPre 跑过dinic后的 状态; 他俩是不一样的)

当然最直接的办法是: 根据图Cur 构造出 restCur残留网络.
即: delete掉restPre_ans这个图, 然后再new 一个新的 restCur, 这自然很耗时.
(因为restCur != restPre_ans + restAdd, 所以 已有的restPre_ans用不上, 只能delete掉)
也就是, 这种办法: 完全是把Pre图 和 Cur图, 当成是2个图, 完全没有任何关系


其实, 比如, Pre图的 最大流是: pre_ans
对于 已得到的restPre_ans 残留网络(此时他的最大流肯定是0, 因为已经榨干了), 直接加上 restAdd后, 得到restNew残留网络
然后对restNew求最大流new_flow
则, pre_ans + new_flow 就是Cur图的最大流.

证明 即, 为什么: (restPre)的最大流 + (restPre_ans + restAdd)的最大流 = restCur的最大流:
对于(restPre_ans + restAdd)这个残留网络, 我们让其中的: restPre_ans(已榨干) 将他恢复成原状: restPre
此时有: (restPre + restAdd), 而他就等于: restCur

算法为:

Graph rest; ' rest为: 残留网络, 他是一个动态的过程 'int maxFlow = rest.dinic();FOR(;;){ ' 模拟 每次从Pre -> Cur的过程 'rest += restAdd;  ' 将新加边 添加到 rest里 'maxFlow += rest.dinic();  ' 这里是重点!!! '' 此时的maxFlow, 就是Cur图的 最大流 '
}

注意, 虽然restAdd里 (有点, 也有边), 但在实际算法里, 只会新加 "边", 即: rest += rsetAdd这个操作, 其实就是对rest进行了addEdge操作
因为在算法上, 新增加点 这太耗时了push_back; 即, 在最开始的rest这个图, 你应该把点数 全部都提前弄出来

流网络的 点和边

流网络里: 点: 是不能存储流量的(除了 源汇点), 点也没有容量的概念, 我们知道wth[i], 而其中的i 是边, 不是点.

(当然, 其实边也不能存储流量…)

边和点, 都不能存储流量

但是: 边, 有"容量 和 流量"的概念, 即: 这个边, {流量: 流过了 多少流量} {容量: 还能流 多少流量}, 这是要记录下来的

(当然, 点也可以有"流量", 即一个点 经过了多少流量 但这也是 通过计算边 来计算点的流量, 但是, 点 没有 容量 这个性质)

虽然, 点不能存储流量, 但是, 点是要: 转移流量/ 流过流量的!!!
可以想象成: 一些入边 流给了: 一个点, 很多流量, 而这个点 需要将这些流量 通过出边, 全部的流出去

即, 虽然每个点, 都是流量守恒, 即( 存储流量为0), 但是, 点 也是有流量这个概念; 点的流量为: 可行流中, 该点 "流过"了的 流量

最小割定理证明

version_0

这里对上图中: 当原G是(b -> a)时, 则有: f(b, a) = 0 做一些证明:

  • 因为原G是b->a, 所以此时的a->b 显然是 原边对应的反向边; 已知c(a, b)=0 残留网络中的c(a,b)表示: 该边 的 容量
    什么叫: 残留网络的边的 容量呢? 很简单, 即该边 还能够 流过多少的流量
    而反向边的容量c(a, b) 等于= 其对应的正向边的流量, 即正向边b->a 已经流过了 c(a, b)的流量
    残留网络中, 正向边的 容量c(b, a) = W(b, a)(W表示, 原图中 该边的初始容量) - f(b, a)(f表示, 该边在可行流中, 已经流经的流量)
    而: 正向边已经流经的流量f(b, a) = 残留网络中反向边的容量c(a, b)
    故, 推出: f(b, a) = c(a, b) = 0

version_1

证: 最大流 = 最小割, 即证: (0, 所有的割 都>= 最大流) (1, 存在某个割 ==等于 最大流)


回顾(割): 对于一个(有向图, 带有起点S, 终点E), (对该图原封不动), 只是把S拉到Lef集合里, E拉到Rig集合里
___然后, 其他点, 要么在Lef, 要么在Rig; 这个操作, 是完全不影响原图的, 点/边/边权等 和原图是一样的
___即: 割的划分形态有很多种2^(n-2), 但是, 不管怎么划分, 所有的割 他们都不会修改原图的!!! 割, 只是对(点)的抽象划分
___那么, 横跨Lef和Rig集合边, 称为(割边); 所有从(Lef->Rig)的割边的边权之和, 为该割的容量


证明0: 所有的割容量 >= 最大流;
___可行流的定义, 即从S到T的流量; 放在(割)里, 即从Lef 流到 Rig的流量;
___因为, 流量 一定<= 容量; 所以, (所有的流 一定<= 任意割的容量)


证明1: 存在某个割容量 == 最大流;
___看这个最大流 的 残留网络; (此时, 这个残留网络里, 不存在任意的可行流)
___在残留网络里, 对S 沿着>0容量的边 进行bfs广搜, 所有可达的点 放到Lef; 剩下的点 放到Rig里
___此时, 这个残留网络的 割, 容量是0; 这个(残留网络的割Cut_0), 他对应一个 (原图的割Cut_1), 即将这个残留网络的割 (点的划分方式) 应用到 原图上, 便可得到Cut_1
___我们看所有的 (从Lef->Rig)的 割边, 他边权为0; 根据(残留网络与原图)的对应规则,
0, 如果该割边是原边; 则意味着: 在原图Cut_1中, 该边是Lef->Rig方向的割边, 且该边在最大流中是(满流)
1, 如果该割边是补充边; 则意味着: 在原图Cut_1中, 该边是Rig->Lef方向的割边, 且该边在最大流中(空流)

此时, 我们证明了: 原图存在一个割Cut_1, 且最大流 在 该割的 所有(Lef->Rig)的割边上, 都是(满流);
但还要证明: 最大流的流量 == Cut_1割的容量

对于任意一个可行流(流就是一个有向图), 他的所有割, 容量均相同, 且均等于 该流的流量.
证明: 任意可行流, 除了S/E, 所有点 不存储流量; 故, 从S->T的流量 等于 从Lef到Rig的流量;

Cut_1割 虽然是原图的割 (不是最大流的割), (上面定理的前提是: 可行流的割, 不是原图的割)
但是, (最大流 经过 所有Cut_1割的 Lef->Rig方向的割边), 故: Cut_1割的容量 = (Cut_1割对应的 最大流的割的容量 == 最大流 (根据上面定理))

Algo_网络流,最大流最小割总结, 残留网络性质,知识点总结Tips相关推荐

  1. 网络流 最大流最小割与最小费用流

    目录 [镇楼] [引入] [基本定义和概念] [最大流算法] [最小割] [最小费用最大流] [引用] [镇楼]   天啦真的好好懂!!!麻麻再也不用担心我的网络流学习啦!!! [引入] 首先,我们来 ...

  2. HDUOJ3549 - Flow Problem(网络流+最大流最小割+模板)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3549 题目大意: 有向图求最大流 解题过程: 关于为什么增加流量时要增加一个反向负流量的边纠结了很久 ...

  3. 最大流最小割经典例题_C/C++知识点之最大流最小割C++实现

    using namespace std; const int MAX=100; const int inf=1<<30; queueQ; int ShortestAugmentingPat ...

  4. 流网络的最小割问题c语言,网络流基础-最大流最小割定理

    最大流最小割定理,指网络流的最大流等于其最小割. 最大流指符合三个性质的前提下,从S到T能流过的最大流量. 最小割指符合割的定义,最小的割容量. 求最大流: 不断寻找增广路,计算能增加的最小流量,然后 ...

  5. hihocoder 网络流二·最大流最小割定理

    网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? ...

  6. 【BZOJ - 1305】dance跳舞(拆点网络流,建图,最大流,残留网络上跑最大流)

    题干: 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲.有一些男孩女孩相互喜欢,而其他相互不喜欢(不会"单向 ...

  7. 洛谷P1344 [USACO4.4]追查坏牛奶Pollutant Control(网络流, 最大流最小割)

    初学网络流:http://blog.csdn.net/wzw1376124061/article/details/55001639 最大流最小割:http://blog.csdn.net/wzw137 ...

  8. 最大流最小割经典例题_最大流, 最小割问题及算法实现

    本博客采用创作共用版权协议, 要求署名.非商业用途和保持一致. 转载本博客文章必须也遵循署名-非商业用途-保持一致的创作共用协议. 由于博文中包含一些LaTex格式数学公式, 在简书中显示不好, 所以 ...

  9. 最大流最小割定理(max flow/min cut theory)

    百度文库里面有个地址,讲的比较详细. http://wenku.baidu.com/link?url=gPXhYCduLNgZaOkKIltNDAgPGwuMTpRX7a0utvVFuqDAP9o1j ...

最新文章

  1. hdu 2067 兔子板
  2. 'yii\base\InvalidRouteException' with message 'Unable to resolve the request site/error.'
  3. 淘宝Fourinone分布式计算框架性能、压力、容灾测试报告
  4. 用php怎么输出饼状图,php绘图之生成饼状图的方法_PHP
  5. micropython是啥 知乎_嵌入式开发必备调试工具:Micro-Lab
  6. 【渝粤题库】陕西师范大学200731 计算机组成原理
  7. MYSQL电脑客户端免安装教程以及出现问题解决方案
  8. redis aof 备份和恢复_Redis 持久化机制的介绍,了解这些流程很重要
  9. val_loss突然变很大_有没有那么一瞬间,你突然觉得释然了?
  10. 【无人机】他把死去的猫做成无人机,网友愤怒了!
  11. 基于JAVA+SpringMVC+Mybatis+MYSQL的博客系统
  12. C# devexpress gridcontrol 分页 控件制作
  13. Python Imaging Library: ImageQt Module(图像QT模块)
  14. 机器学习模型可解释性进行到底 ——PDPICE图(三)
  15. luogu P1015 回文数
  16. 如何优化Flash动画使文件更小播放更流畅
  17. vue怎么安装element-ui教程
  18. Leetcode 1653. Minimum Deletions to Make String Balanced [Python]
  19. 三角形周长最短问题_「初中数学」从三角形周长的最值问题说说解题策略
  20. 撩妹利器之心形函数代码

热门文章

  1. 2018 金华市中小学学生计算机,2018年金华市中小学生校园足球秋季联赛圆满落幕...
  2. python控制nao机器人_python 程序控制NAO机器人行走
  3. 交换机进行syslog服务器设置
  4. 【成神之路】Http网络相关面试题
  5. 手游代理是怎么做的?
  6. long long类型
  7. 2016-ICLR-Order Matters- Sequence to sequence for sets
  8. 002/160 CrackMe Afkayas #1
  9. RNA-seq流程学习笔记(10)-使用HTSeq-count软件对reads进行计数
  10. 离散数学_九章:关系(5)