最大流 学习笔记
搬运自 OI WIKI
概述
网络流基本概念参见 网络流基础。
令
策略 1:Ford–Fulkerson 增广
Ford–Fulkerson 增广是计算最大流的一类算法的总称。该方法运用贪心的思想,通过寻找增广路来更新并求解最大流。
概述
给定网络
对于边
我们将
WARNING
正如我们马上要提到的,流量可能是负值,因此,
我们将
此外,在 Ford–Fulkerson 增广的过程中,对于每条边
TIP
在最大流算法的代码实现中,我们往往需要支持快速访问反向边的操作。在邻接矩阵中,这一操作是 毫无难度的(
初次接触这一方法的读者可能察觉到一个违反直觉的情形 —— 反向边的流量
以下案例有可能帮助你理解这一过程。假设
上有多条增广路,其中,我们选择进行一次先后经过 的增广(如左图所示 流量增加) , 。 - 我们注意到,如果进行中图上的增广,这个局部的最大流量不是
而是 。但由于指向 的边和从 出发的边在第一次增广中耗尽了容量,此时我们无法进行中图上的增广。这意味着我们当前的流是不够优的,但局部可能已经没有其他(只经过原图中的边而不经过反向边的)增广路了。 - 现在引入退流操作。第一次增广后,退流意味着
增加了 剩余容量,即相当于新增 这条边,因此我们可以再进行一次先后经过 的增广(如右图橙色路径所示 无向边) 。 上的流量在两次增广中抵消,我们惊奇地发现两次增广叠加得到的结果实际上和中图是等价的。
以上案例告诉我们,退流操作带来的「抵消」效果使得我们无需担心我们按照「错误」的顺序选择了增广路。
容易发现,只要
最大流最小割定理
我们大致了解了 Ford–Fulkerson 增广的思想,可是如何证明这一方法的正确性呢?为什么增广结束后的流
实际上,Ford–Fulkerson 增广的正确性和最大流最小割定理(The Maxflow-Mincut Theorem)等价。这一定理指出,对于任意网络
为了证明最大流最小割定理,我们先从一个引理出发:对于网络
引理的证明:
为了取等,第一个不等号需要
那么,对于任意网络,以上取等条件是否总是能被满足呢?如果答案是肯定的,则最大流最小割定理得证。以下我们尝试证明。
最大流最小割定理的证明:
假设某一轮增广后,我们得到流
显然,
:此时, ,因此有 ,即 的所有边均满流; :此时, ,即 的所有边均空流。
因此,增广停止后,上述流
容易看出,Kőnig 定理是最大流最小割定理的特殊情形。实际上,它们都和线性规划中的对偶有关。
时间复杂度分析
在整数流量的网络
对于 Ford–Fulkerson 增广的不同实现,时间复杂度也各不相同。其中较主流的实现有 Edmonds–Karp
, Dinic
, SAP
, ISAP
等算法,我们将在下文中分别介绍。
Edmonds–Karp 算法
算法思想
如何在
如果在
上我们可以从 出发 BFS 到 ,则我们找到了新的增广路。 对于增广路
,我们计算出 经过的边的剩余容量的最小值 。我们给 上的每条边都加上 流量,并给它们的反向边都退掉 流量,令最大流增加了 。 因为我们修改了流量,所以我们得到新的
,我们在新的 上重复上述过程,直至增广路不存在,则流量不再增加。
以上算法即 Edmonds–Karp 算法。
时间复杂度分析
接下来让我们尝试分析 Edmonds–Karp 算法的时间复杂度。
显然,单轮 BFS 增广的时间复杂度是
增广总轮数的上界是
增广总轮数的上界的证明
首先,我们引入一个引理 —— 最短路非递减引理。具体地,我们记
不妨称增广路上剩余容量最小的边是饱和边(存在多条边同时最小则取任一
在
接下来我们证明最短路非递减引理,即
最短路非递减引理的证明
考虑反证。对于某一轮增广,我们假设存在若干结点,它们在该轮增广后到
在
中 到 的最短路上,我们记 是 的上一个结点,即 。 为了不让
破坏 的「距离最小」这一性质, 必须满足 。 对于上式,我们令不等号两侧同加,得
。根据反证假设进行放缩,我们得到 。 然后我们尝试讨论
上的增广方向。 假设有向边
。根据 BFS「广度优先」的性质,我们有 。该式与放缩结果冲突,导出矛盾。 - 假设有向边
。根据 的定义我们已知 ,因此这条边的存在必须是当前轮次的增广经过了 并退流产生反向边的结果,也即 。该式与放缩结果冲突,导出矛盾。
- 假设有向边
由于
沿任何方向增广都会导出矛盾,我们知道反证假设不成立,最短路非递减引理得证。
将单轮 BFS 增广的复杂度与增广轮数的上界相乘,我们得到 Edmonds–Karp 算法的时间复杂度是
Dinic 算法
NOTE
由于其对于常见建模情况下的网络具有优秀的时间复杂度,使其成为现阶段相当重要的工具算法
算法思想
考虑在增广前先对
如果我们在层次图
WARNING
尽管在上文中我们仅在单条增广路上定义了增广 / 增广流,广义地
定义层次图和阻塞流后,Dinic 算法的流程如下。
- 在
上 BFS 出层次图 。 - 在
上 DFS 出阻塞流 。 - 将
并到原先的流 中,即 。 - 重复以上过程直到不存在从
到 的路径。
此时的
在分析这一算法的复杂度之前,我们需要特别说明「在
注意到在
多路增广
- 多路增广是 Dinic 算法的一个常数优化 —— 如果我们在层次图上找到了一条从
到 的增广路 ,则接下来我们未必需要重新从 出发找下一条增广路,而可能从 上最后一个仍有剩余容量的位置出发寻找一条岔路进行增广。考虑到其与回溯形式的一致性,这一优化在 DFS 的代码实现中也是自然的。
WARNING
可能是由于大量网络资料的错误表述引发以讹传讹的情形,相当数量的选手喜欢将当前弧优化和多路增广并列称为 Dinic 算法的两种优化。实际上,当前弧优化是用于保证 Dinic 时间复杂度正确性的一部分,而多路增广只是一个不影响复杂度的常数优化。
时间复杂度分析
应用当前弧优化后,对 Dinic 算法的时间复杂度分析如下。
首先,我们尝试证明单轮增广中 DFS 求阻塞流的时间复杂度是
单轮增广的时间复杂度的证明
- 考虑阻塞流
中的每条增广路,它们都是在 上每次沿当前弧跳转而得到的结果,其中每条增广路经历的跳转次数不可能多于 。 - 每找到一条增广路就有一条饱和边消失(剩余容量清零
考虑阻塞流) 。 中的每条增广路,我们将被它们清零的饱和边形成的边集记作 。考虑到 分层的性质,饱和边消失后其反向边不可能在同一轮增广内被其他增广路经过,因此, 是 的子集。 - 此外,对于沿当前弧跳转但由于某个位置阻塞所以没有成功得到增广路的情形,我们将这些不完整的路径上的最后一条边形成的边集记作
。 的成员不饱和,所以 与 不交,且 仍是 的子集。 - 由于
的每个成员都没有花费超过 次跳转(且在使用多路增广优化后一些跳转将被重复计数 因此,综上所述,DFS 过程中的总跳转次数不可能多于) , 。
常见伪证一则
- 对于每个结点,我们维护下一条可以增广的边,而当前弧最多变化
次,从而单轮增广的最坏时间复杂度为 。 - 问题在于
- 「当前弧最多变化
次」并不能推得「每个结点最多访问其出边 次 这是因为,访问当前弧并不一定耗尽上面的剩余容量,结点」 。 可能多次访问同一条当前弧。
- 「当前弧最多变化
注意到层次图的层数显然不可能超过
层次图层数单调性的证明
我们需要引入预流推进类算法(另一类最大流算法)中的一个概念 —— 高度标号。
为了更方便地结合高度标号表述我们的证明,在证明过程中,我们令
对于某一轮增广,我们用
我们给高度标号一个不严格的临时定义 —— 在网络
考察所有
,且剩余容量在该轮增广过程中未耗尽 —— 根据最短路的定义,此时我们有 ,但在该轮增广过程中阻塞流经过 并退流产生反向边 —— 根据层次图和阻塞流的定义,此时我们有 。
以上观察让我们得出一个结论 ——
现在,对于一条
- 假设结点
已加入,结点 正在加入,我们发现,加入结点 后,根据层次图的定义, 的值较 增加 - 与此同时,由于
是 上的高度标号, 的值既可能较 增加 ,也可能保持不变或减少。因此,在整条路径被添加完成后,我们得到 ,其中取等的充要条件是 对于 恒成立。 - 如果该不等式不能取等,则有
—— 即我们想要的结论「层次图的层数在增广过程中严格单增 」 。 - 以下我们尝试证明该不等式不能取等
考虑反证,我们假设
现在我们断言,在
令
但 未取等 - 故根据层次图的定义可知
,并在增广后新一轮重分层中被加入到 中;
- 故根据层次图的定义可知
- 这意味着
这条边的产生是当前轮次增广中阻塞流经过 并退流产生反向边的结果,也即 。
- 这意味着
由于我们无论以何种方式满足断言均得到
常见伪证另一则
- 考虑反证。假设层次图的层数在一轮增广结束后较原先相等,则层次图上应仍存在至少一条从
到 的增广路满足相邻两点间的层数差为 。这条增广路未被增广说明该轮增广尚未结束。为了不产生上述矛盾,原命题成立。 - 问题在于
- 「一轮增广结束后新的层次图上
- 最短路较原先相等」并不能推得「旧的层次图上该轮增广尚未结束」 - 这是因为,没有理由表明两张层次图的边集相同,新的层次图上的
- 最短路有可能经过旧的层次图上不存在的边
- 「一轮增广结束后新的层次图上
将单轮增广的时间复杂度
如果需要令 Dinic 算法的实际运行时间接近其理论上界,我们需要构造有特殊性质的网络作为输入。
由于在算法竞赛实践中,对于网络流知识相关的考察常侧重于将原问题建模为网络流问题的技巧。此时,我们的建模通常不包含令 Dinic 算法执行缓慢的特殊性质;恰恰相反,Dinic 算法在大部分图上效率非常优秀。
因此,网络流问题的数据范围通常较大
特殊情形下的时间复杂度分析
在一些性质良好的图上,Dinic 算法有更好的时间复杂度。
对于网络
在单位容量的网络中,Dinic 算法的单轮增广的时间复杂度为
证明
- 这是因为,每次增广都会导致增广路上的所有边均饱和并消失,故单轮增广中每条边只能被增广一次。
在单位容量的网络中,Dinic 算法的增广轮数是
证明
以源点
为中心分层,记 为 上结点 到源点 的距离。另外,我们定义将点集 定义为编号为 的层次 ,并记 。 假设我们已经进行了
轮增广。根据鸽巢原理,至少存在一个 满足边集 的大小不超过 。 显然,
是 上的 - 割,且其割容量不超过 。 根据最大流最小割定理,
上的最大流不超过 ,也即 上最多还能执行 轮增广。 因此,总增广轮数是
的。
在单位容量的网络中,Dinic 算法的增广轮数是
证明
- 假设我们已经进行了
轮增广。由于至多有半数的( 个)层次包含多于 个点,故无论我们如何分配所有层次的大小,至少存在一个 满足相邻两个层次同时包含不多于 个点,即 且 。 - 为最大化
和 之间的边数,我们假定这是一个完全二分图,此时边集 的大小不超过 。 - 显然,
是 上的 - 割,且其割容量不超过 。 - 根据最大流最小割定理,
上的最大流不超过 ,也即 上最多还能执行 轮增广。 - 因此,总增广轮数是
的。
在单位容量的网络中,如果除源汇点外每个结点
证明
我们引入以下引理 —— 对于这一形式的网络,其上的任意流总是可以分解成若干条单位流量的、点不交 的增广路。
假设我们已经进行了
轮增广。根据层次图的定义,此时任意新的增广路的长度至少为 。 考虑
上的最大流的增广路分解,我们得到的增广路的数量不能多于 ,这意味着 上最多还能执行 轮增广。 因此,总增广轮数是
的。
综上,我们得出一些重要结论:
- 在单位容量的网络上,Dinic 算法的总时间复杂度是
。 - 在单位容量的网络上,如果除源汇点外每个结点
都满足 或 ,Dinic 算法的总时间复杂度是 。对于二分图最大匹配问题,我们常使用 Hopcroft–Karp 算法解决,而这一算法实际上是 Dinic 算法在满足上述度数限制的单位容量网络上的特例。