网络流总结
定义
网络流,简单来讲就是一个有向无负环图,有一个源点,一个汇点。每条边上的边权就是这条边的最大流量。
一个值 \(x\),满足单位时间内源点灌入 \(x\) 单位的水的同时汇点会汇入 \(x\) 单位的水(也就是中间所有节点的流入等于流出,每条边流量不超过容量),这种情况下就是一个合法的网络流。
常见的网络流问题包括但不限于以下类型问题.
最大流问题:对于网络 \(G =(V, E)\),给每条边指定流量,得到合适的流 \(f\),使得 \(f\) 的流量尽可能大.此时我们称 \(f\) 是 \(G\) 的最大流.
最小割问题:对于网络 \(G =(V, E)\),找到合适的 \(s\)-\(t\) 割 \(\{S, T\}\),使得 \(\{S, T\}\) 的总容量尽可能小.此时我们称 \(\{S, T\}\) 的总容量是 \(G\) 的最小割.
最小费用最大流问题:在网络 \(G =(V, E)\) 上,对每条边给定一个权值 \(w(u, v)\),称为费用(cost),含义是单位流量通过 \((u, v)\) 所花费的代价.对于 \(G\) 所有可能的最大流,我们称其中总费用最小的一者为最小费用最大流.
我们先来分析最大流问题。
最大流问题
那你可能要问了,主播主播,我就不能直接从起点出发跑一个 DFS 吗?
看起来没什么问题,但是这样不一定是最优的,我们看一个例子:

最优路线为下:
S->A->T,流量为 1
S->B->T,流量为 1
S->A->B->T,流量为 1
总流量为 3
但是,如果是 DFS,我们可能出现以下的情况:
S->A->B->T,流量为 2
发现已经没法走了,总流量为 2
由此可见, 贪心的走并不能一定让总流量最大。
接下来我们引入一些定义
给定网络 \(G\) 及 \(G\) 上的流 \(f\),我们做如下定义.
对于边 \((u, v)\),我们将其容量与流量之差称为剩余容量 \(c_f(u, v)\),即 \(c_f(u, v) = c(u, v) - f(u, v)\),\(f(u, v)\)表示的是这个边单位时间还最多能多流过多少单位的水。
我们将 \(G\) 中所有结点和剩余容量大于 \(0\) 的边构成的子图称为残量网络 \(G_f\),即 \(G_f = (V, E_f)\),其中 \(E_f = \left\{ (u, v) \mid c_f(u, v) > 0 \right\}\),即现在把所有“还能灌水进去”的水管挑出来(不管水流方向),画成一张新地图。
我们将 \(G_f\) 上一条从源点 \(s\) 到汇点 \(t\) 的路径称为增广路.对于一条增广路,我们给每一条边 \((u, v)\) 都加上等量的流量,以令整个网络的流量增加,这一过程被称为增广.由此,最大流的求解可以被视为若干次增广分别得到的流的叠加。
此外,在 Ford–Fulkerson 增广的过程中,对于每条边 \((u, v)\),我们都新建一条反向边 \((v, u)\).我们约定 \(f(u, v) = -f(v, u)\),这一性质可以通过在每次增广时引入退流操作来保证,即 \(f(u, v)\) 增加时 \(f(v, u)\) 应当减少同等的量。
也就是对于原图里每条边 \(u \to v\),我们都凭空创造一条反向边 \(v \to u\)。
这条反向边的初始流量是 \(0\),容量也是 \(0\)(在原始输入里不存在)。但是剩余容量会随着算法运行而变化。
当你沿着增广路推送流量时,如果走的是:
正向边 \(u \to v\):
\(f(u, v)\) 增加,同时 \(f(v, u)\) 减少同等的量。
反向边 \(v \to u\)(即你走了一条"幻想"的反向路):
\(f(v, u)\) 增加,同时 \(f(u, v)\) 减少同等的量。
你可能问,这个反向边有什么用呢?
我们发现,我们可以将反向边流量的减少视为反向边剩余容量 \(c_f(v, u)\) 的增加——这也与退流的意义相吻合——反向边剩余容量的增加意味着我们接下来可能通过走反向边来和原先正向的增广抵消,代表一种「反悔」的操作。
我们看图:

\(G\) 上有多条增广路,其中,我们选择进行一次先后经过 \(u, v\) 的增广(如左图所示),流量增加 \(1\)。
我们注意到,如果进行中图上的增广,这个局部的最大流量不是 \(1\) 而是 \(2\).但由于指向 \(u\) 的边和从 \(v\) 出发的边在第一次增广中耗尽了容量,此时我们无法进行中图上的增广.这意味着我们当前的流是不够优的,但局部可能已经没有其他(只经过原图中的边而不经过反向边的)增广路了。
现在引入退流操作.第一次增广后,退流意味着 \(c_f(v, u)\) 增加了 \(1\) 剩余容量,即相当于新增 \((v, u)\) 这条边,因此我们可以再进行一次先后经过 \(p, v, u, q\) 的增广(如右图橙色路径所示).无向边 \((u, v)\) 上的流量在两次增广中抵消,我们惊奇地发现两次增广叠加得到的结果实际上和中图是等价的。
所以,我们可以认为建反向边就是代表一种「反悔」的操作。
以上案例告诉我们,退流操作带来的「抵消」效果使得我们无需担心我们按照「错误」的顺序选择了增广路。
容易发现,只要 \(G_f\) 上存在增广路,那么对其增广就可以令总流量增加;否则说明总流量已经达到最大可能值,求解过程完成.这就是 Ford–Fulkerson 增广的过程。
正确性的证明,就是使用“最大流最小割定理”,具体的证明此处从省,仅给出结论。
最大流最小割定理
- 割 (Cut):将顶点集 \(V\) 分为两个集合 \(S\) 和 \(T\),其中 \(s \in S, t \in T\)。
- 割的容量:\(c(S,T) = \sum_{u \in S} \sum_{v \in T} c(u,v)\),即所有从 \(S\) 跨到 \(T\) 的边的容量和。
- 割的净流量:\(f(S,T) = \sum_{u \in S} \sum_{v \in T} f(u,v) - \sum_{u \in S} \sum_{v \in T} f(v,u)\)。
- 在任何网络中,最大流的值等于最小割的容量。

浙公网安备 33010602011771号