【网络流】网络流学习笔记Part2ISAP算法

本文介绍了ISAP算法,一种改进的SAP算法,用于提高寻找最短增广路径的效率。文章详细阐述了ISAP算法的基本原理及实现过程,并对比了其与SAP算法的区别。

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

说实话ISAP的文献真的不太好找= =而且介绍的没有太详细,不像SAP Dinic比较普及。

ISAP其实是改进的SAP算法,要学ISAP就先去看一下SAP好了。(事实上很多人会把ISAP和SAP搞混了。尤其在国内,很多人会直接管ISAP叫SAP)

SAP算法(即Edmonds-Karp算法):

不断进行BFS找增广路径,那么最多找V*E次就一定不存在增广路径了。

时间复杂度 O(V*E^2)

ISAP算法:

通过维护距离标号使得寻找增广路径的过程被简化从而提高效率。距离标号可以使某个点到汇点sink的最少的弧的数量,也可以是源点到该点的最少的弧的数量。通常我们使用前者,这样初始化时就可以通过一次反向的BFS来记录距离标号。

假设点i的距离标号dis[i]=dis[j]+1,则称弧(i,j)为允许弧,在增广时我们只需要找允许弧,就可以使所走路径一定是最短路。

算法的执行:

首先反向BFS初始化距离标号

从源点开始进行增广

设当前访问点为点i

1>若当前i点存在出弧且出弧为允许弧,沿出弧向下执行

2>若当前i点不存在出弧即i为当前路径终点,直接进行增广

3>若当前i点存在出弧但是出弧中不存在允许弧,更新i点的距离标号为所有出弧指向的点的距离标号的最小值+1,之后返回上层。当dis[source]≥顶点数n时,算法全过程停止。

由于蒟蒻太弱了不太会写伪代码,这里引用一下@柔软的小猫点击打开链接的伪代码

algorithm Improved-Shortest-Augmenting-Path
1 f <-- 0
2 从终点 t 开始进行一遍反向 BFS 求得所有顶点的起始距离标号 d(i)
3 i <-- s
4 while d(s) < n do
5 if i = t then // 找到增广路
6 Augment
7 i <-- s // 从源点 s 开始下次寻找
8 if Gf 包含从 i 出发的一条允许弧 (i,j)
9 then Advance(i)
10 else Retreat(i) // 没有从 i 出发的允许弧则回退
11 return f

procedure Advance(i)
1 设 (i,j) 为从 i 出发的一条允许弧
2 pi(j) <-- i // 保存一条反向路径,为回退时准备
3 i <-- j // 前进一步,使 j 成为当前结点

procedure Retreat(i)
1 d(i) <-- 1 + min{d(j):(i,j)属于残量网络Gf} // 称为重标号的操作
2 if i != s
3 then i <-- pi(i) // 回退一步

procedure Augment
1 pi 中记录为当前找到的增广路 P
2 delta <-- min{rij:(i,j)属于P}
3 沿路径 P 增广 delta 的流量
4 更新残量网络 Gf

邻接表优化

如果顶点多的话,往往N^2存不下,这时候就要存边:
存每条边的出发点,终止点和价值,然后排序一下,再记录每个出发点的位置。以后要调用从出发点出发的边时候,只需要从记录的位置开始找即可(其实可以用链表)。优点是时间加快空间节省,缺点是编程复杂度将变大,所以在题目允许的情况下,建议使用邻接矩阵。

GAP优化

如果一次重标号时,出现距离断层,则可以证明ST无可行流,此时则可以直接退出算法。

当前弧优化

为了使每次找增广路的时间变成均摊O(V),还有一个重要的优化是对于每个点保存“当前弧”:初始时当前弧是邻接表的第一条弧;在邻接表中查找时从当前弧开始查找,找到了一条允许弧,就把这条弧设为当前弧;改变距离标号时,把当前弧重新设为邻接表的第一条弧。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值