ISAP 算法
Posted natsuka
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ISAP 算法相关的知识,希望对你有一定的参考价值。
(quad) Dinic 算法其实已经足够处理大多数的网络流了,但还不够快。接下来介绍的是最优秀的增广路最大流算法:ISAP(Improve Shortest Argumenting Path)。它的时间复杂度上界与 Dinic 一样,为 (O(n ^ 2 cdot m))。
(quad) 先分析 Dinic 的优化空间。Dinic 必须在每一次 dfs 前通过 bfs 获取一次所有点的深度(Depth),这样做效率是极其低下的。ISAP 通过一种神奇的方法解决了这个问题。
(quad) ISAP 对深度有不同的定义。对于一个点 (i),它的深度 (dep_i) 为源点 (s) 到汇点 (t) 的最短距离与它到源点 (s) 的最短距离的差。另外,定义 (gap_i) 为所有满足 (dep_j = i) 的点 (j) 的数量,即所有深度为 (i) 的点数。显然,当 (exists i) 使得 (gap_i = 0) 时,即分层图出现断层时,残余网络中不存在一条自 (s) 到 (t) 的增广路。
int dfs(int node, int flow){
if(node == t || !flow)
return flow;
int stream = 0, f;
for(int i = head[node]; i != -1; i = edge[i].next)
if(dep[edge[i].to] == dep[node] - 1 && (f = dfs(edge[i].to, min(flow, edge[i].capacity)))){
flow -= f, stream += f;
edge[i].capacity -= f, edge[i ^ 1].capacity += f;
if(!flow)
return stream;
}
......
return stream;
}
(quad) 上面是 ISAP 的 dfs 代码片段。可以发现,除了隐藏的省略号部分,它和 Dinic 的是几乎一样的。而隐藏部分是为了更新 (dep) 和 (gap),省去多次的 bfs。
(quad) 执行“......”的先决条件是 (flow
eq 0)。此时说明该点 (node) 已经没有出边能够接受流量了,那么只需要
if(--gap[dep[node]++])
++gap[dep[node]];
else
gap[s] = n + 1;
即可更新 (dep) 和 (gap)。
(quad) 这样的算法不但优秀,也很好写,可以作为网络流的主要算法。
以上是关于ISAP 算法的主要内容,如果未能解决你的问题,请参考以下文章