網路流 最大流

2021-08-06 02:32:19 字數 3156 閱讀 4755

網路流

題記:網路流是最近講過的最迷演算法……

網路流(network-flows)是一種模擬水流的解決問題方法,與線性規劃密切相關。非常重視選手在網路流上的建模技巧,畫圖是非常關鍵的。

1、最大流

問題引入:

有n條溝渠,與水坑s、t相連,匯聚成m個點,第i條溝渠的水流的流量為c[i],每乙個點的流入量和流出量都要相等,水由原點水坑s,匯聚到水坑t,求可以有多少水可以匯聚過去。

(poj. 1273)

如圖所示:

可以將問題進行如下整理:

(1)用c[e]表示每條邊最大的可能流量

(2)每條邊對應的實際流量為f[e]

(3)根據條件,可知所有的f[e]<=c[e]

(4)目標是最大化從s發出的水流量

問題分析:

很容易會想到貪心演算法,但很明顯,貪心不一定是最優的,如果從某乙個地方,流過全部的水,那麼從其他地方便不能再用這條溝渠了。

舉個例子:如圖1為某個資料用貪心演算法所得的值,由某一條溝渠開始流過,盡可能地多流,最後得出最多的水為10。

但最優解應該是圖2,正確答案為11。那麼是**多了了呢?

不防用正解與貪心做法流過水的差值做乙個對比,通過對流量的差可以發現,我們通過將原先得到的流給推回去(圖中的-1部分),而得到了新的流,從而達到最優解。

為什麼貪心得不到最優解:

當貪心得到一定的值的時候,那麼這條溝渠便不在能用,把很多原來可能是可以流過去的水給卡在那裡,而匯聚不到t點,用wyy的說法來說,可能會「擋路」。

在這裡大概講一下,畫幾個樣例便會明白。

最大流的定義:

我們稱使得傳輸量最大的f為最大流,而求解最大流的問題稱為最大流問題。而我們學的是增廣路演算法。

關於反向邊的建立:

如上面說到的正解,是通過把流推回去而得到的,這麼說明,需要有乙個反悔的機會,即不選擇流過原來那麼多水,這下反向邊就很關鍵了。

圖中曲線為建立的反向邊,直線為正向邊。當水流過正向邊的時候,正向邊還可以流過的水量自然要減去已經流過的f,而同時也可以返回f的流水,也就是給反向邊的邊權變為f。

這樣的好處是,下一次再掃路徑發現會有更優時,可以倒退回去,當然,不管是走反向邊還是走正向邊,都要把另一條邊加上流過的水量,以便與以後反悔。

心情增廣路的定義(注意不是針管路哦):

我們所考慮的f[e]0的e對應的反向邊所組成的圖稱為殘餘網路,並稱殘餘網路上s->t的路徑為增廣路。

ford和fulkerson迭加演算法:

便是在貪心演算法的基礎上的迭代

把各條弧上單位流量的費用看成某種長度,用求解最短路問題的方法確定一條自v1至vn的最短路;在將這條最短路作為可擴充路,用求解最大流問題的方法將其上的流量增至最大可能值;

而這條最短路上的流量增加後,其上各條弧的單位流量的費用要重新確定,如此多次迭代,最終得到最大流。

具體實現:

我採用的是陣列模擬指標的方法,畢竟指標不怎麼會用,而用vertor怕不能準確地找到它的反向邊。

陣列模擬指標因為是按順序儲存,把正向邊標為0,反向邊標為1,先存正向邊,再存反向邊。

「無限」跑dfs,直到找不到一條能由s=1到t=n的路徑。每一次在路徑上取最小的流量(mi),這樣可以確保每一段路減去mi不會為負數。同時要更改此時還可以流過的流量(va),因為已經流過了這麼多水,要用原來的va-mi,同時要把對面的邊(正邊找反邊,反邊找正邊)加上這麼多(可後悔的值)。

這裡順便說一下怎麼找對面的邊:要找當前的反向邊時,只用加一即可,如果找正向邊,就減一。這樣會好理解一點,因為他們是按順序儲存的!!也可以用異或,**更簡潔。

時間複雜度:

最多進行深度為f次深度優先搜尋,所以其複雜度為o(f|e|),最壞的情況基本上不存在。所以在多數情況下,及時得出的複雜度偏高,實際運用中還是比較快的。

#include

#include

#include

#include

using namespace std;

const int maxn=205,oo=10000005;

int n,m,a,b,c,s,t,ans;

int cur=-1,head[maxn];

bool v[maxn];

struct water

edge[2*maxn];

void add(int from,int to,int va,int type)

int dfs(int now,int mi)

}

h=edge[h].next;

} return 0;

} int main()

while(1)

cout<

<

網路流(最大流)

我們圍繞一道題來講解吧 藍橋杯 演算法訓練 網路流裸題 首先,何為網路流最大流問題?可行流 對於每條路線 u,v 上給定乙個實數f u,v 滿足 0 f u,v c u,v 則稱f u,v 為路線 u,v 的流量。而對於一組具有源點和匯點,且總流出量 總流入量,則稱為網路中的一條可行流。拿例子來說 ...

網路流 最大流

dinic 最大流 head x 從0開始記 這樣便於找反向邊 異或即可 當前弧優化 include include include include include include include define ll long long define ull unsigned long long d...

網路流最大流

源點 起始點 匯點 目標點 流 從源點到匯點的一條路徑 容量 每條管道允許通過的最大流量 流量 通過一條邊的水的實際體積 最大流等於最小割 從起點到終點的一條路徑 尋找從s到t的一條增廣路 在紅色的路線裡,路徑的一條最小流量是3,那麼這條路徑上的邊都減去3,同時反向邊加上3 這條增廣路的乙個流量是3...