網絡流之增廣路算法


這部分內容在《算法競賽入門經典》——劉汝佳 里面講的已經很詳細了。但里面對於反向流量的作用是沒有說明的。這里只說一下反向流量的作用。

推薦上http://www.cnblogs.com/g0feng/archive/2012/05/29/2524749.htm看下。

 

反向流量能夠讓后面的流自我調整。

例如當前狀態下

當前狀態下如何尋找?

用a表示殘量, cap表示容量,很明顯,3-4這條路不是最優的.

此時BFS, 會得到 a[2] = 2, a[4] = 2, a[3] = 1 (提示:cap[4][3]-flow[4][3]=1), a[5]=1, a[6]=1, a[7]=1

更新流量得到

可以看到,通過方向流量,使得網絡流自我調整到最優。

 

 附上代碼:

#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 20;
const int INF = (1<<30);

int cap[maxn][maxn], flow[maxn][maxn];
int n;

int EdmondsKarp(int s, int t) {
    int p[maxn], a[maxn];
    queue<int> q;

    memset(flow, 0, sizeof(flow));
    int f = 0;

    while(true) {
        memset(a, 0, sizeof(a));

        a[s] = INF;

        q.push(s);

        while(!q.empty()) { //BFS 找增廣路
            int u = q.front(); q.pop();

            for(int v=1; v<=n; v++) if(!a[v] && cap[u][v]>flow[u][v]){
                //找到新節點v
                p[v] = u; q.push(v);
                a[v] = min(a[u], cap[u][v]-flow[u][v]);
            }
        }

        if(a[t] == 0) break;    //找不到,則當前流已經是最大流

        for(int u=t; u != s; u = p[u]) {    //從匯點往回走
            flow[p[u]][u] += a[t];  //更新正向流量
            flow[u][p[u]] -= a[t];  //更新反向流量
        }

        f += a[t];  //更新從 s 流出的流量
    }

    return f;
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM