最大網路流 增廣路演算法

2021-09-30 16:34:15 字數 3293 閱讀 1972

幾句廢話:

讀了劉汝佳的書之後,感覺一切都是那麼茫然,於是自己在網上找教程,自己一點點碼的,大概用了三天。

網路流基礎:

看來我很有必要說一下網路流的基礎

網路流問題就是給你乙個圖,每個圖的邊權叫做這條邊的流量,問你從起始點出發,有多少值能通過這些邊流到重點

我知道你沒看懂,舉個例子:

如圖:最大值為

從1到2到4運6個

從1到2到3到4運1個

從1到3到4運3個

一共運10個。

舉例說完了,那麼我說幾個定義:

容量,就只一條邊的權值,表示能從這條邊運送的最大值

流量,表示一條邊實際上流過的最大值

那麼,說演算法的時間到了,還是先上資料

(資料為上圖所示)

45//

四個點,五條邊12

8133

2312

4634

5

開始,我們假設所有邊的流量都是0

以這個資料,這樣可以達到。

於是我們試圖增加一些變得流量,使得重點的流量更大。

那麼如何增加?就需要我們找増廣路。

什麼是増廣路,就是一條從起點,到終點的一條每條邊容量-實際流量》的路0。

比如

0/8表示一條邊流量為0,容量為8

現在很明顯可以看出,存在一條増廣路1——2——4

然後怎麼辦,把這條路上的每條邊流量都加上每條邊容量與流量差的最小值

例如8-0>6-0 因此1——2、2——4這兩條邊的流量都加上6,並且答案也加上6

然後我們繼續找増廣路,又發現一條1——2——3——4

還是按剛才的,找出最小值,為1,所以這條增光路上每一邊流量加1

然後ans再加一變成7

然而我們繼續找増廣路,發現1——3——4

按照剛才,流量加上2,變成

ans加上3變成10

然後發現沒有増廣路了,於是演算法結束,答案是10.

等等,這就要上**了?傳說中得noi演算法網路流就這麼簡單?不存在的

細心的同學(滑稽)會發現,這種情況就很神奇

你可能回算1——2——3——4這條増廣路,於是答案是1,但是事實證明最優答案明顯是2,那麼問題出在**?

因為我們沒有給予返回的機會,也就是相當於第一次找到的不是最優解,那麼怎麼辦?

所以,我們要有乙個反向邊,來給程式反悔的機會,每條邊都建立一條反向邊,反向邊的初始容量是0,流量都為負數。

假設1——2這條邊本來權值是1,流量也是1,那麼他的反向邊的容量是0,流量是-1,這個應該好理解。

上圖就會變為下圖:

然後以剛才舉例,當確定増廣路1——2——3——4後,圖是這樣的:

於是,我們又找到了一條新的増廣路:1——3——2——4

(因為0-(-1)=1,所以這條邊也可以走)

那麼答案是1+1=2

那麼問題來了,為什麼這樣就算一種呢?

因為製造相反邊,如2——3,就是相當於吧原來從而流到3的量流回來了。

這樣就可以求出最大值。

口胡內容就到這裡,其實我寫的不是很清楚,大家看劉汝佳的可能會更清楚一些,但是重點來了!!!

這道題**實現非常之困難,至少對於我來說,所以劉汝佳的**我壓根沒看懂。

因此,我自己寫得乙份淺顯易懂的**

沒有vector!!!沒有指標!!!

而且有複雜的注釋!!!

#include #include 

#include

#include

#include

#include

#include

using

namespace

std;

int n,m;//

n個點,m條邊

int head[100010];//

這是鄰接表的標誌,head[i]表示以i為頂點的第一條邊

struct

edge

map[100010

];int index=-1;//

鄰接表輸入陣列

int flag=0;//

退出的標記

void build_edge(int a,int b,int c)//

構造鄰接表,插入連線表

int bfs()//

運用bfs找到増廣路

}if(min_flow[n]!=0)//

如果終點得到更新,說明找到増廣路,直接break

break

; }

if(min_flow[n]==0)//

當沒有更新到終點,也就是重點最小增加值為0時,說明沒有増廣路了,直接完事

flag=1

;

for(int e=n;;e=map[p[e]].from)//

從終點開始,以此倒著走増廣路,把沿途上邊的流量都加上終點最小更新值

return min_flow[n];//

返回最小更新至,加到答案當中

}int

max_flow()

return flow;//

返回答案

}int

main()

for(int i=1;i<=m;i++)//

讀入,構造鄰接表

cout

/輸出答案 }/*

測試資料

4 41 2 2

2 4 2

1 3 3

3 4 1

*/

學資訊不易,作業還沒動,求關注!!!

最大網路流 增廣路演算法

幾句廢話 讀了劉汝佳的書之後,感覺一切都是那麼茫然,於是自己在網上找教程,自己一點點碼的,大概用了三天。網路流基礎 看來我很有必要說一下網路流的基礎 網路流問題就是給你乙個圖,每個圖的邊權叫做這條邊的流量,問你從起始點出發,有多少值能通過這些邊流到重點 我知道你沒看懂,舉個例子 如圖 最大值為 從1...

最大網路流演算法

最大網路流,需要的準備是 bfs,ek演算法 用pre陣列記錄前驅節點,用vis判斷是否訪問過 用g二維陣列表示殘餘網路,用f二維陣列表示實際流網路 下面這篇部落格詳細介紹了最大網路流 既然已經有了輪子,那我就不造了 下面是我的 include include include include usi...

最大網路流

求網路流有很多演算法,這幾天學習了兩種,記錄一下ek演算法。首先是網路流中的一些定義 v表示整個圖中的所有結點的集合.e表示整個圖中所有邊的集合.g v,e 表示整個圖.s表示網路的源點,t表示網路的匯點.對於每條邊 u,v 有乙個容量c u,v c u,v 0 如果c u,v 0,則表示 u,v ...