最大流——HLPP算法

本文介绍了最高标号预流推进(HLPP)算法,这是一种用于解决最大流问题的高效算法,具有令人惊讶的时间复杂度。文章详细阐述了算法思想,包括将网络节点视为水池,预流推进过程,以及如何通过预处理降低复杂度。此外,还列出了算法步骤,并提供了代码实现。最后,作者表达了初次写作的谦逊态度,欢迎读者提出建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

名字长,跑得快:最高标号预流推进算法!

最高标号预流推进算法High Level Preflow Push是最大流里最快的算法。我是偶然在网上看到这个算法的,其时间复杂度达到了令人发指的O(|E|²*sqrt(|V|))(Dinic,SAP,ISAP都是O(|E|²*|V|)!)。但是查了半天资料,发现关于这个算法的讲解十分少。经过一周多的钻研,终于差不多搞懂了:)。

非常感谢石姐的鼎力相助!


目录


算法思想

  • 预流推进算法将每个点看做一个可以存储流的“水池”,其中存有流的点称为活动节点;
  • 对于每个非s或t的点,流入该点的流只可能有两个去向:流入汇点t,流回源点s;
  • 预流推进算法从源点开始沿边向其它点推流,之后每次选一个活动节点通过推流,试图使其变得不活动。当所有节点都是不活动节点时,算法就结束了;
  • 以上是传统预流推进算法的主要思想。而最高标号预流推进算法就是先预处理了一个距离标号h,通过优先队列,没次选出h最大的点进行推流,以减少重复操作,降低了复杂度。

算法步骤

  1. 通过bfs预处理出距离标号h,即到达汇点t的最短距离;
  2. 将从源点s出发的边设为满流,到达的点v标记为活动节点并加入到优先队列中;
  3. 从优先队列中不断取出点u进行推流操作,要求到达点v的必须满足h(u)==h(v)+1
最高标号预流推进算法(High-Level Preflow Push, HLPP)是一种常用的最大流算法。它的基本思想是将节点按照高度分类,按照高度从高到低进行推进流量,同时维护一个优先队列,以保证高度最高的节点优先处理。该算法可以在$O(V^2\sqrt{E})$的时间复杂度内求解最大流,其中$V$和$E$分别表示节点数和边数。 算法的具体步骤如下: 1.初始化:将源点$s$的距离$d(s)$设为$|V|$,其余节点的距离$d(v)$设为$0$,并将源点的流量$f(s,v)$设为该边的容量$c(s,v)$。 2.进行预流推进:对于每一个非汇点$v\neq t$,如果$f(s,v)>0$,则将流量$f(s,v)$推进到邻接点中距离$d(v)$最小的点上去,如果邻接点的距离$d(u)=d(v)-1$,则可以推进的流量为$\delta=f(s,v)-f(v,u)$,否则可以推进的流量为$f(s,v)$。如果推进后$f(s,v)$变为$0$,则将节点$v$从高度$h$的桶中移除,并将其加入高度$h+1$的桶中。 3.进行流量推进:从高度最高的桶开始,对于每一个节点$v$,如果$f(s,v)>0$且存在一条从$v$出发的饱和边$(v,u)$,则将流量$\delta=\min(f(s,v),c(v,u)-f(v,u))$从$v$推进到$u$,如果推进后$f(v,u)=c(v,u)$,则将节点$v$从高度$h$的桶中移除,并将其加入高度$h+1$的桶中。 4.重贴标签:如果节点$v$的高度$d(v)$小于$|V|$,且存在一条从$v$出发的非饱和边$(v,u)$,则将节点$v$的高度$d(v)$更新为$d(u)+1$。 5.重复步骤3和4,直至无法再推进流量或者汇点$t$不再可达。 最终的最大流即为源点$s$流出的总流量。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值