網路最大流Dinic

2022-07-31 07:36:13 字數 1484 閱讀 9008

1.什麼是網路最大流

形象的來說,網路最大流其實就是這樣乙個生活化的問題:現在有乙個由許多水管組成的水流系統,每一根管道都有自己的最大通過水流限制(流量),

超過這個限制水管會爆(你麻麻就會來找你喝茶qwq)。現在,給定你乙個出水口(原點),乙個出水口(匯點),求這個網路中水流量的最大值。

????看起來很簡單對不對?在我們看起來的確是這樣的,而這部分的難點也確實不在思路上,而是在於演算法設計以及**實現上。

2.怎麼求解網路最大流

首先想明白一件事情,對於乙個節點來說,他接受的流量一定小於等於他給出的流量之和,否則,水管一定會爆掉。而對於乙個節點來說,

他接受的流量有可能大於任意乙個他出邊的流量,因為這個節點可以把接受流給出到不同的水管上,進而實現分流。

有了這兩點,思路就很清晰了(貪心算):

1.首先,我們需要尋找一條可行的流量方案(此時,不一定為最大流量)。

2.然後我們依次擴充套件這條路徑上的所有節點,看看這個節點是否還可以接受流量,直到已經滿流。

3.重複上述步驟,直到沒有可行流動路徑。

4.此時我們累加的流量即為網路最大流,我們把這種方法稱為最大流dinic演算法

3.實現細節

這種演算法看起來簡單,實際上實現起來會遇到許多小毛病,以及許多很難理解的**實現,這裡舉乙個栗子

在步驟2的時候我們採用dfs進行擴充套件,也稱為網路最大流的擴充套件部分演算法,需要借助到反邊這樣乙個概念,即:兩個節點a,b間有一條權值為w無向邊。

我們就把他拆分成一條由a指向b的有向邊與一條由b指向a的有向邊,其中,這兩條邊的權值之和為w,這樣一來一回,兩者相互抵消巧妙的實現了回溯

上**:qwq

#include#include#include#include#define n 1000005

#define m 4*1000005

#define inf 0xfffffff

using namespace std;

int read()//快讀

while(c<='9'&&c>='0')

return num*k;

}struct node

;node edge[2*m];

int cnt_edge=1,n,m,s,t;

long long ans=0;

int last[n],deep[n];

void add_edge(int u,int v,int w)

bool bfs() //判斷是否有通路

} }return deep[t]!=-1;

}int dfs(int now,int flow) //flow為當前流量

} return flow-delta; //返回這裡留下去了多少 ,即當前點的最大流量

} int main ()

while(bfs()) ans+=dfs(s,inf);

printf("%lld\n",ans);

return 0;

}

看完關注哦~

網路最大流 Dinic

dinic求最大流分為兩步 bfs構造層次圖 dfs尋找增廣路 字面理解,其實就是給圖分層 設源點為第0層 從源點出發最少只要一步可以到達的就是第1層 最少兩步到達的是第二層 依次類推直到匯點 如下圖所示 在網路流中 求取層次圖需要先判斷該邊是否有剩餘容量 若層次圖可以延伸到匯點 則說明最大流還可以...

網路最大流 Dinic

存圖方式 鄰接表,鄰接矩陣 圖的遍歷 dfs,bfs 我們舉個例子吧 有乙個毒瘤水管工,他會造水管,有一天他造了乙個水管網路,就像乙個圖。其中有乙個點只有出邊,就是起點,還有乙個點只有入邊,是終點。點之間有一些管子,這些管子都有單位時間內的容量,現在毒瘤水管工想知道,他的管子在單位時間裡在起點終點之...

網路流最大流 Dinic演算法

o n 2 m 的演算法 比ek的o n m 2 優很多 ek通常解決10 3 10 4規模的網路 而dinic能解決10 4 10 5的網路 dinic演算法的思想也是分階段地在層次網路中增廣。它與最短增廣路演算法不同之處是 最短增廣路每個階段執行完一次bfs增廣後,要重新啟動bfs從源點vs開始...