最大流模板(Edmonds Karp)

2021-06-11 07:03:00 字數 1685 閱讀 1007

最近在看網路流,看了演算法導論不是很懂。。不知道書裡那個圖是不是錯了,搞得我有點混亂;

然後就從網上查下資料,翻了幾個大神的部落格,就搞懂了個大概是怎麼回事;網路流裡有很多

演算法,因為是入門,所以就寫了個ek(edmonds-karp)求最大流的演算法,順便做了個模板題;

寫的時候還行,大概思路沒什麼問題,就是實現的時候有點小錯誤,下面是本人學習中的一些理解:

edmonds-karp求最大流的演算法核心思想就是不斷找增廣路,每找到一條增廣路,記錄增廣路中

邊流量最少的值d,然後讓當前找到增廣路中的每一條正向弧減去d,讓反向弧加上d,當不再找

到增廣路的時候,就證明當前的總流量已經是最大流;至於怎樣找增廣路。。一致認為bfs是最好

的方法了。。。

增廣路(摘自nocow):設f 是乙個可行流,w是發點到收點的一條有向道,如果w滿足下列條件,稱之為關於可行流f的一條可增廣道

(又稱可擴道):

1. 每條正向弧是非飽和弧,

2. 每條反向弧是非零流弧.

為什麼要有反向邊或者殘餘圖?

前面我們確定了一條路徑的最小流量之後,我們實際上可以把這部分流量從圖中刪去(這個可以看做減治的過程):因為這個路徑以後是不會更改的,而且路徑之間互不影響。但是也會出現一定的問題:結果往往不是最優的。反向邊和殘餘圖可以解決這一問題。

最近又看了演算法導論之後,看到了個可以作為不加反向弧而得不到最優解的反例,如下圖

第一張圖是最原始的圖,值為邊的容量,第二張圖是找出s->v1->v2->t增廣路後不加反向弧的殘餘圖;明顯的,如果不加反向弧,v1->v2一旦成為飽和弧後,就不能恢復,而這樣最後算出來的流值是199,但是正確的最大流值是200,所以不加反向弧不能保證得到的是最優解(這算是證明麼- -!);

poj 1273(drainage ditches),可以用來測試下**寫得對不對,第一次做網路流的題,紀念下。。

#include #include #include #include using namespace std;

const int inf=0xfffff;

const int n = 330;

int maxflow, pre[n], dp[n][n];

void edmonds_karp(int start, int end, int m)

} if(pre[end] == 0) //頂點的父親為空,表示找不到增廣路,很容易理解吧。。

break;

for(int i = end;i != start;i = pre[i]) //找出增廣路中最小殘餘量

minflow = min(minflow, dp[pre[i]][i]);

for(int i = end;i != start;i = pre[i])

maxflow+=minflow; }}

int main()

maxflow = 0;

edmonds_karp(1, m, m);

printf("%d\n", maxflow);

} return 0;

}

模板 網路最大流 最大流

給出乙個網路圖,以及其源點和匯點,求出其網路最大流。in put role presentation inp utin put4 5 4 3 4 2 30 4 3 20 2 3 20 2 1 30 1 3 40ou tput role presentation out puto utpu t50最大...

模板 網路最大流 最大流

給出乙個網路圖,以及其源點和匯點,求出其網路最大流。in put role presentation inp utin put4 5 4 3 4 2 30 4 3 20 2 3 20 2 1 30 1 3 40ou tput role presentation out puto utpu t50最大...

最大流模板

2015年1月30日更新 include include include include include include include include include include include include typedef unsigned int uint typedef long lo...