关于dinic算法中当前弧如何优化问题

刚开始学最大流dinic算法时,并没有运用优化,但是也解决了一些题。后来在做hdu的3572时,一直超时,被卡时间。所以上网查了下,了解到dinic中必须要加当前弧优化才可以过。然后查了下当前弧优化是什么鬼,网上的解释也是比较模糊,自己便思考了一番,于是说一下自己的想法。

当前弧优化就是为了防止走重复的边,从而较少了时间。

int dfs(int k,int y)
{
    if(k==maxl+1)return y;
    int f;
    for(int i=cur[k]; i<V[k].size(); i++)
    {
        cur[k]=i;//如果这条路径可行,下次dfs到k顶点时从顶点k中编号为i的边开始找。
        Lu L=Ed[V[k][i]];
        if(L.flow>0&&dis[L.to]==dis[k]+1&&(f=dfs(L.to,min(y,L.flow))))
        {
            Ed[V[k][i]].flow-=f;
            Ed[V[k][i]^1].flow+=f;
            return f;
        }
    }
    return 0;
}

我们知道dinic算法中的dfs是为了在可行增广路中找到最小容量。而找增广路需要遍历每个点所连接的边,直至找到一条可到达终点的路。例如,我们在第一次dfs时找到了一条增广路:顶点1中的第3条边,顶点2中的第4条边,顶点3中的第4条边,顶点5中的第2条边。这四条边是我们在第一次dfs寻找到的可行路,我们可以看到,每次找增广路时都是从某个顶点所连接的第一条边开始,那也就是说从顶点1中的第1条边接着去找没找到,从而遍历到顶点1中的第3条边,接着去找发现顶点2中的前三条边也没找到。。。这样下去直到找到终点。那么,我们可以知道下次dfs时,顶点1的前两条边没用(下次bfs或者几次bfs后可能会有用),直接从顶点1的第三条边开始去找。

当我们将当前图的所有增广路都找到后,再次bfs分层,当前图的层次会发生变化,然后我们在从顶点1开始去找,所以我们每次bfs,都要清一下数组cur。

 while(bfs())
        {
            memset(cur,0,sizeof(cur));//清零,给以后的dfs记录
            while(res=dfs(1,inf))ans+=res;
        }

鄙人语言能力不强,能力有限,如果有错误和漏洞,请各位大佬批评指正,谢谢。

猜你喜欢

转载自blog.csdn.net/zyy_1998/article/details/79339969
今日推荐