网络流 & 二分图小记
网络流的性质
增广路定理
加了反向边之后网络流可以以任意顺序增广,增广路不存在时一定为最大流。
最大流最小割定理
网络的最大流等于最小 \(S-T\) 割。
从线性规划的角度看最大流与最小割互为对偶。
增量加边
由于有增广路定理,在对网络流加边后,只要再跑一次网络流算法就能得到新的最大流。
退流删边
删边比加边困难,如果不能转化为加边,可以通过退流删边。
假如要删 \(u\rightarrow v\) 这条边,当前这条边流量为 \(k\),则我们只需要让流入 \(u\) 的流量和流出 \(v\) 的流量减少 \(k\),然后删除 \(u\rightarrow v\)。具体来说,从 \(u\) 到 \(S\) 跑一次最大流量为 \(k\) 的最大流,从 \(T\) 到 \(v\) 跑一次最大流量为 \(k\) 的最大流,然后将 \(u\rightarrow v\) 和其反向边的边权置为 \(0\)。
费用流的性质
贪心增广
每次走最短的增广路,当增广路不存在时必然为最小费用最大流。
凸性
每次走一条增广路后新的增广路长度单调不降,因此费用是关于流量的凸函数。
消圈定理
对于一个合法的最大流,不断找图中的负圈并且添加围绕负圈的流,当找不到负圈时流是最小费用最大流。
增量加边
消圈本身效率极低,所以费用流算法一般不增量加边,但是模拟费用流或者通过费用流推导贪心算法时可以手动进行增量加边操作。
首先加边后我们先把新出现的增广路加入流,使得流最大,然后不断消除负圈,由消圈定理我们知道最后总能得到最小费用最大流。
效率优化:primal-dual 和 zkw
使用类似 dinic 的 dfs,但是每次走最短的增广路,在某些图上会有较小的运行时间,但是时间复杂度较 EK 没有变化,仍然是伪多项式复杂度 \(O(nmf)\)。
注意到效率的瓶颈在于每次都需要跑一个 \(O(nm)\) 的最短路算法,参照 Johnson 算法,我们尝试给每个节点赋一个势能 \(h_x\),并调整边 \(u\xrightarrow{w}v\) 的边权为 \(w+h_u-h_v\),使得边权非负,然后使用 Dijkstra 求最短路。
考虑初始时令势能为最短路,每轮增广后让势能加上当前的最短路,可以证明这样设置势能后边权非负。需注意势能可能会很大,小心 overflow。
w` = w + h[u] - h[v]
...
spfa(s, t);
while (dijkstra(s, t)) {
memcpy(cur, head, sizeof(cur));
maxflow += dfs(s, inf, t);
for (int i = 1; i < cnt; i++) h[i] += dis[i];
}