弱多项式复杂度最小费用流算法
前言
Ouuan Orz
当然,先说一下弱多项式是啥?
OI 界中叫做 Dinic 和 EK 的那两个最大流算法,把其中的 BFS 改成求最短路,复杂度都是与值域多项式相关的,即复杂度是伪多项式的。
多项式复杂度有弱多项式和强多项式两种,弱多项式就是关于输入长度( $n$、 $m$ 之类的,以及 $log 值域$ )为多项式复杂度,强多项式就是在加减乘除为 $O(1)$ 时复杂度关于数据规模为多项式(就是说跟值域完全无关,只和 $n, m$ 之类的相关,复杂度关于 $n, m$ 之类的为多项式)。
当然,这时 Ouuan 说的。
算法讲解
要求
- $st$ 无入边,$ed$ 无出边。
- 可以有负环。
无源汇最小费用流
对于有源汇最小费用最大流的定义我们改一下:
没有 $st$ 和 $ed$,同时最小化 $\sum\limits_{(i,j)∈E} cost(i,j)*f(i,j)$ 。
当然,这个时候你可能会好奇这个我们讲的有源汇最小费用最大流有个 $der$ 的关系?
那如果我们从 $ed$ 向 $st$ 连接一条无限小的边,使得流量越多越好,然后后面减掉就行了。
做法
首先,这个流是最小费用当且仅当图中不存在负环,证明和上篇重制版最小费用最大流博客雷同,不予以赘述。
首先明白一个定理:如果把每条边容量乘 $2$,则对应流量乘 $2$,最小费用乘 $2$,因为乘 $2$ 一定不存在负环。
那么接下来就非常简单了,把边权拆成二进制,维护残余网络 $G$ ,一开始 $G$ 中的容量和流量都为 $0$,然后二进制从高到低扫描,每一位把所有边的容量和流量乘 $2$,但是需要注意,有些边这一位二进制可能为 $1$,因此这条边会加入到残余网络中,这就非常的蛋疼了,好的方法是这条边是 $(x,y)$,在加入前从 $y$ 跑一遍最短路,如果 $d[x]+cost(x,y)<0$ ,那么就不加入,并且把 $y$ 到 $x$ 的最短路的流量全部减一,当然,如果这条边原本就存在,则直接流量 $+1$ 即可。
至于为什么直接跑最短路即可,因为我们维护的残余网络中一定没有负环啊。
时间复杂度: $O(nm^2\log{U})$ ,$U$ 是边中的最大流量。
1 |
|
细节
无限小?
坑
边权?
坑
总结
放心,因为比赛一般都是构图题,难以卡掉 $ZKW$ 和 $EK$,所以,大胆的,放心的用 $ZKW$ 吧,学这个算法就图一乐。
参考资料
洛谷的讨论:https://www.luogu.com.cn/discuss/show/161006
弱多项式复杂度算法非常非常好的常考资料,真的非常非常好:https://ouuan.github.io/post/%E5%9F%BA%E4%BA%8E-capacity-scaling-%E7%9A%84%E5%BC%B1%E5%A4%9A%E9%A1%B9%E5%BC%8F%E5%A4%8D%E6%9D%82%E5%BA%A6%E6%9C%80%E5%B0%8F%E8%B4%B9%E7%94%A8%E6%B5%81%E7%AE%97%E6%B3%95/
坑
要准备 NOIP 啦,赛后补充 Dij 的做法,还有亿点细节补充。
代码也要补点注释。
赛前还是直接打个简单思路就去准备比赛了。