我的dinic演算法網路流(詳註解)

2021-06-08 21:38:23 字數 1940 閱讀 2033

/*題目大意:求乙個圖中起點s到終點t的最大流除以s到t的的所有路徑中的最大流量的那條路徑流量值;

(雖然這樣看起來比較簡單,但說實話,這題我讀題至少都花了半個小時,直到ac的的前一秒我都有點怕題意讀錯)

此題主要要求兩個量:整個圖的最大流和一路徑的最大流量值;

最大流maxflow沒什麼好說的,直接套模板(不過此題完全照搬是不行的,需要做一點修改),

雖然我本打算自己去實現的練練手的,但是當我正打算手動實現的時候,阮學長建議我大比賽的

時侯有模板盡量用模板,所以我就去拿到了那本模板書, 照著敲,發現這模板卻是寫得好,要讓我敲得話,

肯定至少得花乙個小時左右!完全套模板的不能ac的原因是: 這題的head[i]存放的是-1,而模板卻是把它作為0來處理的,

所以的對模板做了一下修改! 另外在敲得過程中發現他的cur[maxn]純粹屬於浪費空間,果斷刪除!

一路徑的最大流量值maxedge,之前阮學長打算以求最大路徑的方法來求這個值,當我看到他用到spafa演算法的時候,

我就知道他這裡可能理解錯了,所以和他討論,他也將他的**刪掉了,後來討論用深搜的方法求,

但是感覺 有環,處理起來很麻煩,阮和王相去討論另一道題了,之後我又想了想,

為什麼不在求最大流的時候,注入我的maxedge,後來果斷打擂方式,一較短的**一次性ac!  

雖然最大網路流都已經是很經典的模板了,感覺沒多大必要講的,但是有考慮到如果只會套模板,

不知裡面的工作原理,在正式比賽中很難隨需求任意修改模板裡面的處理細節!

所以我還是在下面大概說一下最大流的一種比較經典的,也比較實用的乙個網路流演算法吧

第一步:以原點s為根節點,將所有的節點按深度分層,(這個模板有個比較beautiful的地方就是利用路徑陣列ps來做佇列

,節省了很大的空間)直到將匯點t找到為止,如果直到最後都沒找到t那 說明沒有路徑了!最大流搞定!

第二部:從s開始,一 層一層的向下尋找t,找到之後,求出最小容量邊tr,以此為流量將各邊減去tr,在將各邊的反向邊加tr!

跳到第三步;

第三部: 回溯到f點(f點是滿足離s最近且,以該點為端點的邊容量被減為了0);之後跳到第二步,繼續尋找到t的路徑!當找不到t的時候,

又跳到第一步;

註解提供者:ghq(springwater)

*/

#include#include#define maxn 20

#define maxe 40

#define typec int

const typec inf = 0x3f3f3f3f;

struct edgebf[maxe];//bf用來查詢某節點相連的所有節點

int ne,head[maxn],ps[maxn],dep[maxn];

void addedge(int x,int y,typec c)

typec flow(int n,int s,int t)}}

}if(dep[t]==-1)break;//當發現不能分層,說明已經找不到匯點,最大網路流結束!

for(i=s,top=0;;)

for(j=head[i];j!=-1;j=bf[j].nxt)//從當前點i找乙個可以到達的點bf[j].y

if(bf[j].c&&dep[i]+1==dep[bf[j].y])break;

if(j!=-1)//當找到乙個可以到達的點,則可以跳到下一層,把當前點i改變為下一層的點bf[j].y,並將j放到為路徑ps堆疊裡

else//當當前 i點,不能跳轉到下一層,則需要回溯}}

return res;

}int main()

maxedge=0;

maxflow=flow(n,s,t);

ans=(double)maxflow/(double)maxedge;

printf("%d %0.3lf\n",cas,ans);

}return 0;

}

網路流dinic演算法

遇到過不少網路流的題目,直接找增廣路徑的方法時間複雜度實在受不了。常面臨tle的問題。通過學習這個dinic演算法,不僅 短,效率也高。該演算法的重點在於乙個層次圖,是在普通增廣的方法上加了優化,普通的增廣是每次在圖上四處遊蕩,直到找到匯點為止。dinic演算法就是把每個點都給乙個等級level l...

網路流Dinic演算法

我的模板 例題 struct edge edge int llst,int ffrom,int tto,int ccap,int fflow lst llst from from to tto cap ccap flow fflow dinic 演算法有3個重點 乙個是 層次圖 乙個是 阻塞流 乙個...

Dinic快速網路流演算法

edmonds karp演算法,每進行一次增廣,都要做一遍bfs。如果能少做幾次bfs,即可提高效率,dinic演算法可以減少bfs次數。dinic演算法的關鍵 在一次增廣的過程中,尋找多條增廣路徑。使用dfs 先利用bfs對殘餘網路 包括原網路 分層 乙個節點的 層 數,就是源點到它最少要經過的邊...