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 算法的主要内容,如果未能解决你的问题,请参考以下文章

试题库问题(最大流Isap) 网络流

ISAP网络流算法

ISAP算法对 Dinic算法的改进

最短增广路Isap算法 网络流

ISAP 算法

网络流算法总汇(ek,dinic,isap)