名字长,跑得快:最高标号预流推进算法!
最高标号预流推进算法High Level Preflow Push
是最大流里最快的算法。我是偶然在网上看到这个算法的,其时间复杂度达到了令人发指的O(|E|²*sqrt(|V|))
(Dinic,SAP,ISAP都是O(|E|²*|V|)!)。但是查了半天资料,发现关于这个算法的讲解十分少。经过一周多的钻研,终于差不多搞懂了:)。
非常感谢石姐的鼎力相助!
目录
算法思想
- 预流推进算法将每个点看做一个
可以存储流
的“水池”,其中存有流的点称为活动节点
; - 对于每个非s或t的点,流入该点的流只可能有两个去向:流入汇点t,流回源点s;
- 预流推进算法从源点开始沿边向其它点推流,之后每次选一个活动节点通过推流,试图使其变得不活动。当所有节点都是不活动节点时,算法就结束了;
- 以上是传统预流推进算法的主要思想。而
最高
标号预流推进算法就是先预处理了一个距离标号
h,通过堆
或优先队列
,没次选出h最大的点进行推流,以减少重复操作,降低了复杂度。
算法步骤
- 通过bfs预处理出距离标号h,即到达汇点t的最短距离;
- 将从源点s出发的边设为
满流
,到达的点v标记为活动节点
并加入到优先队列中; - 从优先队列中不断取出点u进行推流操作,要求到达点v的必须满足h(u)==h(v)+1