题意
给出一个网络图,以及其源点和汇点,求出其网络最大流。
题解
最大流问题就是,给你一张网络图,如果点 到点 有一条边,边权为 ,那么点 到点 最多 流 的流量。求 汇点 最多能流到多少流量(源点流量无限)。
一个容易被想到的 错解
每次枚举一条从 源点 到 汇点 的路径,然后流 这条路径上所能流的最大流量。
Hack:
ford-fulkerson
如何把上面的算法改对呢?
维护退流。
即每次从 到 流 的流量,就在反向边 到 也流 的流量,这样做的意义就是让我们有反悔的机会。
ford-fulkerson
就是暴力 DFS 模拟增广过程。
复杂度 , 就是最大流。
这个复杂度显然不太优,
要是给它这张图跑的话,它就会跑 次。
dinic
如何改进 ford-fulkerson
呢?
每次只考虑增广到与 源点 距离差为 的边。这样的话,dinic
就会把中间那条边权为 的边删除,这样流两次就搞定了。
优化
- 当前弧优化:
是已经被 访问过的点,现在 要访问 ,那就不用在尝试给 流量了,因为它们必然没有剩余流量。 - 炸点优化:
如果 到汇点的路径上已经没有剩余流量了,就可以把 炸掉,即以后再访问到 时,立刻退出。
加上优化后 dinic
复杂度是 。
求方案
根据残量网络可以反推出方案。
代码: