ford-fulkerson演算法是通過深度優先搜尋尋找增廣路,並沿著它增廣。
與之相對,dinic演算法總是尋找最短的增廣路,並沿著它增廣。因為最短增廣路的長度在增廣過程中始終不會變短,所以無需每次都通過寬度預先搜尋來尋找最短增廣路。
我們可以先進行一次寬度優先搜尋,然後考慮由進距離頂點指向遠距離頂點的邊所組成的分層圖,在上面進行深度優先搜尋尋找最短增廣路。
如果在分層圖上找不到新的增廣路,則說明最短增長路的長度確實邊長了,或不存在增廣路,於是重新通過寬度優先搜尋構造新的分層圖。每一步構造分層圖的複雜度為o(|e|),而每一步完成之後最短增廣路的長度都會至少增加1,由於增廣路的長度不會超過|v|-1,因此最多重複o(|v|)步就可以了。
另外,在每次對分層圖進行寬度優先搜尋尋找增廣路時,如果避免對一條沒有用的邊進行多次查詢,就可以保證複雜度為o(|e||v|),這樣總的複雜度就是o(|e||v|^2)。
以hdu1532為例,這題用ford-fulkerson演算法會超時,而用dinic演算法就不會。
1 #include 2 #include 3 #include4 #include 5 #include 6
#define inf 0x3f3f3f3f
7using
namespace
std;
8const
int max = 220;9
intn, m;
10struct
nod ;
13 vectorg[max];
14int
level[max], iter[max];
15void add_edge(int
from, int to, int
cap) );
17 g[to].push_back((nod));18}
19void bfs(int
s) 32}33
}34}35
int dfs(int v, int t, int
f) 46}47
}48return0;
49}50int max_flow(int s, int
t) 59}60
intmain()
67 printf("
%d\n
",max_flow(1
,m));
68for(int i = 0; i <= m; i ++) g[i].clear();69}
70return0;
71 }
Dinic演算法求最大流
include using namespace std const int oo 1e9 無窮大 const int maxm 111111 邊的最大數量,為原圖的兩倍 const int maxn 999 點的最大數量 int node,src,dest,edge node節點數,src源點,de...
最大流模版Dinic演算法
網路流的演算法有很多,最基礎的為ek演算法,他的時間複雜度為o n m 2 dinic演算法的時間複雜為o m n 2 dinic演算法是現構造層次圖,然後用阻塞流來增廣。構造層次圖有乙個bfs,增廣是用dfs來寫。詳細的講述請參考 劉汝佳寫的 演算法競賽入門經典訓練指南 大白書 include i...
最大流之Dinic演算法
之前簡單介紹了最大流之ford fulkerson演算法,此演算法時間複雜度為o f e 大多數情況下,這個演算法已經足夠高效了,但當頂點數或最大流流量非常大時,這個演算法就顯得不夠快了。下面簡單介紹易實現的dinic演算法。ford fulkerson演算法通過深度優先搜尋尋找增廣路,並沿著它增廣...