说实话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
原文地址:http://blog.csdn.net/creationaugust/article/details/43635023