幾句廢話:
讀了劉汝佳的書之後,感覺一切都是那麼茫然,於是自己在網上找教程,自己一點點碼的,大概用了三天。
網路流基礎:
看來我很有必要說一下網路流的基礎
網路流問題就是給你乙個圖,每個圖的邊權叫做這條邊的流量,問你從起始點出發,有多少值能通過這些邊流到重點
我知道你沒看懂,舉個例子:
如圖:最大值為
從1到2到4運6個
從1到2到3到4運1個
從1到3到4運3個
一共運10個。
舉例說完了,那麼我說幾個定義:
容量,就只一條邊的權值,表示能從這條邊運送的最大值
流量,表示一條邊實際上流過的最大值
那麼,說演算法的時間到了,還是先上資料
(資料為上圖所示)
45//開始,我們假設所有邊的流量都是0四個點,五條邊12
8133
2312
4634
5
以這個資料,這樣可以達到。
於是我們試圖增加一些變得流量,使得重點的流量更大。
那麼如何增加?就需要我們找増廣路。
什麼是増廣路,就是一條從起點,到終點的一條每條邊容量-實際流量》的路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 ...