20220104-EK求最大流
EK求最大流
1. 最大流知识点梳理
- 基本概念
- 流网络,不考虑反向边
- 可行流,不考虑反向边
- 两个条件:容量限制、流量守恒
可行流的流量=从源点流出的流量-流入源点的流量
- 最大流是指最大可行流
- 残留网络,考虑反向边,残留网络的可行流$f^{‘}$ + 原图的可行流$f$ = 原图的另一个可行流
|f' + f| = |f'| + |f|
|f'|
可能是负数
- 增广路径
- 割
- 割的定义
- 割的容量,不考虑反向边,最小割是指容量最小的割
- 割的流量,考虑反向边,
f(S, T) <= c(S, T)
- 对于任意可行流$f$,任意割
[S, T]
,有|f| = f(S, T) <= c(S, T)
- 最大流最小割定理
- 可行流$f$是最大流;
- 可行流$f$的残留网络中不存在增广路;
- 存在某个割
[S, T]
,有|f| = c(S, T)
;
- 算法【网络流的时间复杂度just a joke】
- EK算法 $O(nm^2)$
- Dinic算法 $O(n^2m)$
- 应用
- 二分图:二分图匹配、二分图多重匹配
- 上下界网络流:无源汇上下界可行流、有源汇上下界最大流、有源汇上下界最小流
- 多元汇最大流
2. EK算法具体实现
思路:首先存下图,建立反向边,构建残余网络,在残余网络中不断寻找增广路径,维护残余网络,将其累加至答案中,知道找不到增广路径。具体代码如下:
1 |
|
3. Dinic算法具体实现
概念:在稀疏图上和EK算法效果差不多,但是在稠密图上优势明显。
思路:EK算法在寻找增广路径时候是一条一条找的,显然比较低效。因此Dinic实现了多路增广;
- 多路增广:在使用EK算法时,由于我们使用bfs找增广路,当每次贪心取得一条增广路并增广后,我们从汇点沿着增广路往前走,很可能会遇见一些点实际经过的流量小于该点所有入度的容量和,或者说在残量网络中,该点的入度和出度均大于0。我们可以利用该店后向弧的残量向该点前向弧增广。由于涉及回溯,bfs不适用;
- 当前弧优化:对于增广操作,对于任意节点,我们每增广它的一条前向弧,意味着这条弧后所有的边都被我们多路增广过了,当我们再次处理该节点时,可以不用考虑这条弧。或者说,如果一条边已经被增广过,那么它就没有可能被增广第二次。那么我们下一次进行增广时,可以不走那些已经被增广过的边。
1 |
|