關於最大流增廣路徑演算法的正確性的證明

2021-08-26 15:41:27 字數 1476 閱讀 4327

最大流增廣路徑演算法也叫ford-fulkerson演算法,這個演算法的思想很簡單。即找一條從s到t的增廣路徑,然後對找到的增廣點列進行流值的修改,一直迭代直到沒有增廣路徑結束。

具體步驟:

d={v,a,s,t,c}中每一條弧的值初始化為0 1.

s是源點,設點集 u={s},弧的集合 b為空集 ;

2. 弧 a 滿足下列條件之一則加入u;

(1) a 流出u && f (a)< c (a) ; a加入b;

(2) a 流入u && f (a) > 0 ;a加入b;

3. 重複2。

4. (1) 若u中沒有 t 則 f 是最大流;

(2) 若u中有 t 則f 不是最大流,且進行如下步驟;

① 從 b 中找到乙個 s 到 t 的增廣路徑 s-x1-x2······xm-t 。(其實是點列)

② 改變點列上每一條弧的值

如果點列是順著弧 a 的方向的則 f (a) = f (a) + 1;

如果是逆著弧 a 的方向的則 f (a) = f (a) - 1;

③ 其它弧上的流大小不改變。

④ s -> t 的流增加1,轉到1。

現在證明 f 是最大流的充要條件是不存在增廣路徑

「=>」

這個方向很明顯,如果存在一條增廣路徑則 f 可以增加,f顯然不是最大流。

"<="方向比較複雜,我們先證明任意的流小於等於任意乙個極小割的容量。

這個很明顯,設定乙個有效的流,因為每乙個極小割可以把圖分為兩部分a和b,對於s和t之外的每乙個點x,流向x的量等於從x流出的量,所以從a流向b的流和網路的流相等且 <= 這個極小割的容量,這個割是任意的。

由於圖中每條弧的容量確實,所以最大流確定,由於每一輪演算法 f 的值增加1,所以最終能得到乙個不含t的點集u,(3)結束後點集u劃分了乙個 s - t 割 ,並且把圖分成a和b兩部分,u中包含所有s能達到的頂點。由於不存在增廣路徑,則對於 s-t 割中所有流出u的弧有 f(u,v) == c(u,v),對於所有流入u的弧有 f (u,v) == 0 ;如果 s-t 割不是最小割 ,則存在乙個割的容量小於 f 也和前面的證明產生矛盾,所以此時 s-t 割是最小割。

把 s-t 割中的每條弧的流值相加得到從 a 流向 b 的流,也是整個網路的流f。顯然由每條邊f(u,v) = c(u,v) 知 f == c (s - t)。

若 f 不是最大流,則存在 f 』 > f ,則 f 『 大於 s-t 割的容量,和前面的證明矛盾,所以 f 是最大流,同時最大流也等於最小割,"<="方向成立。

然後是演算法的完善:

每一次的f值可以增加 min{c(s,x1)-f(s,x1) , c(x1,x2) - f(x1,x2) ······,c(xm,t)-f(xm,t) };因為若min{c(s,x1)-f(s,x1) , c(x1,x2) - f(x1,x2) ······,c(xm,t)-f(xm,t) }< 1 ,則增加 1 之後一定能找到一條相同的增廣路徑。所以不妨一次性使這條路徑達到飽和!

by zhr2010

證明增廣路演算法的正確性

一直對增廣路這種貪心思想表示懷疑,今天看到乙個很好的證明 首先介紹割的概念,所謂圖的割,指的是某個頂點集合s屬於v,從s出發的所有邊的集合成為割 s,v s 這些邊的容量和被稱為割的容量,如果有源點s屬於s,匯點t屬於v s,則稱之為s t割,如果將s t割的所有邊都在原圖中去掉,則不再有s t的路...

證明增廣路演算法的正確性及dinic演算法的使用

一直對增廣路這種貪心思想表示懷疑,今天看到乙個很好的證明。首先介紹割的概念,所謂圖的割,指的是某個頂點集合s屬於v,從s出發的所有邊的集合成為割 s,v s 這些邊的容量和被稱為割的容量,如果有源點s屬於s,匯點t屬於v s,則稱之為s t割,如果將s t割的所有邊都在原圖中去掉,則不再有s t的路...

最大流的增廣路演算法

模板題目鏈結 洛谷p3376 模板來自演算法競賽入門經典 第2版 劉汝佳 include using namespace std define inf 0x3f3f3f3f typedef long long ll const int maxn 100010 struct edge 記錄這條邊的資訊...