dinic在資訊學奧賽中是一種最常用的求網路最大流的演算法。
它憑藉著思路直觀,**難度小,效能優越等優勢,深受廣大oier青睞
$dinic$演算法屬於增廣路演算法。
它的核心思想是:對於每乙個點,對其所連的邊進行增廣,在增廣的時候,每次增廣「極大流」
這裡有別於ek演算法,ek演算法是從邊入手,而dinic演算法是從點入手
在增廣的時候,對於乙個點連出去的邊都嘗試進行增廣,即多路增廣
dinic演算法還引入了分層圖這一概念,即對於$i$號節點,用$dis(i)$表示它到源點的距離,並規定,一條邊能夠被增廣,當且僅當它連線的兩個點$u,v$滿足:$dis(v)=dis(u)+1$,這樣可以大大優化其時間複雜度。
有了上面的知識,dinic實現起來也就比較簡單了。
每次bfs構造分層圖(注意必須每次都重新構造,因為每次增廣之後會刪除一些無用的邊,也就會刪除一些無用的點)
然後從源點開始多路增廣
dinic演算法的理論時間複雜度為$o(n^2*m)$
證明可以看這裡
但是!dinic演算法的效能在比賽中表現的非常優越。
按照集訓隊大佬ly的說法,我們可以認為dinic演算法的時間複雜度是線性的(比某標號演算法不知道高到**去了)
題目鏈結
#include#include#include
#define addedge(x,y,z) add_edge(x,y,z),add_edge(y,x,0);
using
namespace
std;
const
int maxn=1e6+1
;const
int inf=1e8+10
;inline
char
nc()
inline
intread()
while(c>='
0'&&c<='9')
return x*f;
}int
n,m,s,t;
struct
node
edge[maxn*4
];int head[maxn],cur[maxn],num=0;//
注意這裡必須從0開始
inline void add_edge(int x,int y,int
z)int
deep[maxn],q[maxn];
inline
bool
bfs()
}return
deep[t];
}int dfs(int now,int
nowflow)
}return
totflow;
}void
dinic()
printf("%d
",ans);
}int
main()
dinic();
return0;
}
網路最大流演算法 Dinic演算法及優化
dinic在資訊學奧賽中是一種最常用的求網路最大流的演算法。它憑藉著思路直觀,難度小,效能優越等優勢,深受廣大oier青睞 dinic 演算法屬於增廣路演算法。它的核心思想是 對於每乙個點,對其所連的邊進行增廣,在增廣的時候,每次增廣 極大流 這裡有別於ek演算法,ek演算法是從邊入手,而dinic...
網路流最大流 Dinic演算法
o n 2 m 的演算法 比ek的o n m 2 優很多 ek通常解決10 3 10 4規模的網路 而dinic能解決10 4 10 5的網路 dinic演算法的思想也是分階段地在層次網路中增廣。它與最短增廣路演算法不同之處是 最短增廣路每個階段執行完一次bfs增廣後,要重新啟動bfs從源點vs開始...
網路流 最大流Dinic演算法
突然發現到了新的一年什麼東西好像就都不會了涼涼 建殘量網路圖 在殘量網路圖上跑增廣路 重複1直到沒有增廣路 注意乙個殘量網路圖要盡量把價值都用完,不然會浪費建圖的時間 include include include include include include include include in...