Flow
ianwen
Flow Networks
網路流
# Flow Networks
網路的定義:
- 有向圖
- 邊權是 容量(capacity) ,c(u, v) > 0
- c(u, v) = 0時,edge(u, v)即不存在
- 一張圖有 源點(s) 跟 匯點(t)
- 對於每個點v,必存在 s → v → t
# Flow Networks
V3
V1
S
T
V4
V2
16
12
13
14
9
4
4
7
20
這是一張網路
# Flow Networks
V3
V1
S
T
V4
V2
16
12
13
14
9
4
4
7
20
這是一張網路
源點
# Flow Networks
V3
V1
S
T
V4
V2
16
12
13
14
9
4
4
7
20
這是一張網路
匯點
# Flow Networks
V3
V1
S
T
V4
V2
16
12
13
14
9
4
4
7
20
這是一張網路
容量
# Flow Networks
Flow(流)的定義:
- 一個節點到另一個節點的"流動"量
- 以 f(u, v) 表示,流向為u → v
- 有正負,代表方向,即: f(u, v) = -f(v, u)
- 流量不能大於容量
V2
V1
10/12
f(V1, V2) = 10
f(V2, V1) = -10
# Flow Networks
Flow(流)守恆:
- 除源點與匯點外,每個節點的總流入=總流出
- 源點的總流出=匯點總流入
V1
10/12
3/6
1/4
x/19
x=12
# Flow Networks
Flow(流)的🌰:
V3
V1
S
T
V4
V2
11/16
12/12
8/13
8/14
1/9
1/4
4/4
4/7
15/20
f(S, V1) + f(S, V2) = 19
f(V3, T) + f(V4, T) = 19
一樣耶~
Maximum-flow
最大流問題
# Maximum-flow
最大化流量:
- 給定一張網路與每個邊的容量
- 求最大有多少流量可以流過這張圖
- 即求 f(源點, 匯點) 最大值
# Maximum-flow
Dinic's Algorithm 迪尼茨演算法
- 時間複雜度
- 運用 Blocking Flow 與 Level Graph
O(VE2)

由 Yefim Dinitz 於1970年提出
# Maxmium-flow
Blocking Flow (阻塞流)
- 在此情形下,已沒有路徑可以從源點走到匯點
- 一張圖可以有多種Blocking Flow
- Maximum Flow必為Blocking Flow
# Maximum-flow
Blocking Flow (阻塞流)的🌰
S
T
V1
V2
2/9
2/2
2/2
0/9
0/9
S
T
V1
V2
9/9
0/2
2/2
2/9
9/9
f(S, T) = 2
f(S, T) = 11
Maximum Flow
Blocking Flow
# Maximum-flow
找 Blocking Flow (阻塞流)
- 找一條源點走到匯點的路徑
- 對路徑上的每條邊 容量 -= 路徑上最小容量
- 回到第一步,直到找不到任何一條路徑
- 得到其中一種Blocking Flow
# Maximum-flow
找 Blocking Flow (阻塞流)
V3
V1
S
T
V4
V2
16
12
13
14
9
4
7
20
# Maximum-flow
找一條路徑
V3
V1
S
T
V4
V2
16
12
13
14
9
4
7
20
# Maximum-flow
減去最小值
V3
V1
S
T
V4
V2
16-12
12-12
13
14
9
4
7
20-12
# Maximum-flow
找一條路徑
S
T
V4
V2
13
14
9
4
7
V3
V1
4
0
8
# Maximum-flow
減去最小值
S
T
V4
V2
13-7
14-7
9
4
7-7
V3
V1
4
0
8-7
# Maximum-flow
找一條路徑
S
T
V4
V2
5
7
9
4
0
V3
V1
4
0
1
# Maximum-flow
減去最小值
S
T
V4
V2
5-4
7-4
9
4-4
0
V3
V1
4
0
1
# Maximum-flow
找不到下一條路徑,找到阻塞流了
S
T
V4
V2
1
3
9
0
0
V3
V1
4
0
1
# Maximum-flow
Level Graph (層次圖)
- 原圖的子圖
- 將離出發點的距離作為層次
- 保留所有節點,僅保留由高層級往低層級的邊
# Maximum-flow
找 Level Graph (層次圖)
V2
V1
V3
V4
T
S
# Maximum-flow
找 Level Graph (層次圖) - BFS
S
T
V1
V2
V3
V4
S
1
1
# Maximum-flow
找 Level Graph (層次圖) - BFS
S
T
V1
V2
V3
V4
S
1
1
2
2
# Maximum-flow
找 Level Graph (層次圖) - BFS
S
T
V1
V2
V3
V4
S
1
1
2
2
3
# Maximum-flow
Dinic's Algorithm
- 建立 Residual Graph (剩餘圖)
- 建立 Residual Graph 的Level Graph
- 對Level Graph找Blocking Flow
- Residual Graph相應邊減去Blocking Flow減的值
- 回到第一步驟,直到Level Graph找不到Blocking Flow
- 原圖 (Capacity) - 剩餘圖(Residual) = 流量(Flow)
- 最後找到的流量必為最大值
# Maximum-flow
原圖
S
T
V1
V2
V3
V4
10
10
1
4
8
9
10
10
6
# Maximum-flow
初始化
Residual Graph
S
T
V1
V2
V3
V4
S
T
V1
V2
V3
V4
10
10
1
4
8
9
10
10
6
10
10
1
4
8
9
10
10
6
# Maximum-flow
建層次圖
Residual Graph
S
1
1
Level Graph
S
T
V1
V2
V3
V4
10
10
1
4
8
9
10
10
6
# Maximum-flow
建層次圖
Residual Graph
Level Graph
S
1
1
2
2
S
T
V1
V2
V3
V4
10
10
1
4
8
9
10
10
6
# Maximum-flow
建層次圖
Residual Graph
Level Graph
S
1
1
2
2
3
S
T
V1
V2
V3
V4
10
10
1
4
8
9
10
10
6
# Maximum-flow
建層次圖
Residual Graph
Level Graph
S
1
1
2
2
T
S
T
V1
V2
V3
V4
10
10
1
4
8
9
10
10
6
10
10
4
8
9
10
10
# Maximum-flow
Level Graph找Blocking Flow
Residual Graph
Level Graph
S
1
1
2
2
T
S
T
V1
V2
V3
V4
10
10
1
4
8
9
10
10
6
10/10
4/10
4/4
6/8
4/9
10/10
4/10
# Maximum-flow
Residual Graph減去Blocking Flow
Residual Graph
Level Graph
S
1
1
2
2
T
S
T
V1
V2
V3
V4
10/10
4/10
4/4
6/8
4/9
10/10
4/10
10-10
10-4
1
4-4
8-6
9-4
10-10
10-4
6
# Maximum-flow
更新Residual Graph
Residual Graph
S
T
V1
V2
V3
V4
0
6
1
0
2
5
0
6
6
Level Graph
S
1
1
2
2
T
10/10
4/10
4/4
6/8
4/9
10/10
4/10
# Maximum-flow
更新Residual Graph
Residual Graph
S
T
V1
V2
6
1
2
5
6
6
Level Graph
S
1
2
T
10/10
4/10
4/4
6/8
4/9
10/10
4/10
V3
V4
1
2
# Maximum-flow
加入反向邊
Residual Graph
S
T
V1
V2
6
1
2
5
6
6
Level Graph
S
1
2
T
10/10
4/10
4/4
6/8
4/9
10/10
4/10
V3
V4
1
2
4
10
6
4
10
4
4
# Maximum-flow
刪除舊的Level Graph,進入新循環
Residual Graph
S
T
V1
V2
6
1
2
5
6
6
V3
V4
4
10
6
4
10
4
4
# Maximum-flow
建立層次圖
Residual Graph
S
T
V1
V2
6
1
2
5
6
6
V3
V4
4
10
6
4
10
4
4
Level Graph
S
4
1
2
6
5
6
6
3
3
6
# Maximum-flow
Level Graph找Blocking Flow
Residual Graph
S
T
V1
V2
6
1
2
5
6
6
V3
V4
4
10
6
4
10
4
4
Level Graph
S
4
1
2
6
5
6
6
3
3
6
# Maximum-flow
Level Graph找Blocking Flow
Residual Graph
S
T
V1
V2
6
1
2
5
6
6
V3
V4
4
10
6
4
10
4
4
Level Graph
S
4
1
2
5/6
5/5
5/6
5/6
3
3
0/6
# Maximum-flow
Residual Graph減去Blocking Flow
Residual Graph
S
T
V1
V2
6-5
1
2
5-5
6-5
6-5
V3
V4
4
10
6-0
4
10
4
4
Level Graph
S
4
1
2
5/6
5/5
5/6
5/6
3
3
0/6
# Maximum-flow
更新Residual Graph
Residual Graph
S
T
V1
V2
1
1
2
0
1
1
V3
V4
4
10
6
4
10
4
4
Level Graph
S
4
1
2
5/6
5/5
5/6
5/6
3
3
0/6
# Maximum-flow
更新Residual Graph
Residual Graph
S
T
V1
V2
1
1
2
1
1
V3
V4
4
10
6
4
10
4
4
Level Graph
S
4
1
2
5/6
5/5
5/6
5/6
3
3
0/6
# Maximum-flow
加入反向邊
Residual Graph
S
T
V1
V2
1
1
2
1
1
V3
V4
9
10
6
4
10
9
9
Level Graph
S
4
1
2
5/6
5/5
5/6
5/6
3
3
0/6
5
# Maximum-flow
刪除舊的Level Graph,進入新循環
Residual Graph
S
T
V1
V2
1
1
2
1
1
V3
V4
9
10
6
4
10
9
9
5
# Maximum-flow
建立層次圖
Residual Graph
S
T
V1
V2
1
1
2
1
1
V3
V4
9
10
6
4
10
9
9
5
Level Graph
S
∞
1
∞
1
∞
∞
# Maximum-flow
Level Graph找Blocking Flow
Residual Graph
S
T
V1
V2
1
1
2
1
1
V3
V4
9
10
6
4
10
9
9
5
Level Graph
S
∞
1
∞
1
∞
∞
# Maximum-flow
找不到,跳出迴圈
Residual Graph
S
T
V1
V2
1
1
2
1
1
V3
V4
9
10
6
4
10
9
9
5
Level Graph
S
∞
1
∞
1
∞
∞
# Maximum-flow
刪除Level Graph與反向邊
Residual Graph
S
T
V1
V2
1
1
2
1
1
V3
V4
# Maximum-flow
Capacity - Residual = Flow
Residual Graph
S
T
V1
V2
1
1
2
1
1
V3
V4
S
T
V1
V2
V3
V4
10
10
1
4
8
9
10
10
6
Capacity Graph
減
# Maximum-flow
Maximum Flow = 19
S
T
V1
V2
V3
V4
10/10
9/10
0/1
4/4
6/8
9/9
10/10
9/10
5/6
9+10 = 19
# Maximum-flow
扣
const long long INF = 1LL<<60; struct Dinic { //O(VEE) static const int MAXN = 1005; struct Edge{ int u, v; long long cap, rest; }; int n, m, s, t, d[MAXN], cur[MAXN]; vector<Edge> edges; vector<int> G[MAXN]; void init(){ edges.clear(); for ( int i = 0 ; i < n ; i++ ) G[i].clear(); n = 0; } int add_node(){ return n++; } void add_edge(int u, int v, long long cap){ edges.push_back( {u, v, cap, cap} ); edges.push_back( {v, u, 0, 0LL} ); m = edges.size(); G[u].push_back(m-2); G[v].push_back(m-1); } bool bfs(){ fill(d,d+n,-1); queue<int> que; que.push(s); d[s]=0; while (!que.empty()){ int u = que.front(); que.pop(); for (int ei : G[u]){ Edge &e = edges[ei]; if (d[e.v] < 0 && e.rest > 0){ d[e.v] = d[u] + 1; que.push(e.v); } } } return d[t] >= 0; } long long dfs(int u, long long a){ if ( u == t || a == 0 ) return a; long long flow = 0, f; for ( int &i=cur[u]; i < (int)G[u].size() ; i++ ) { Edge &e = edges[ G[u][i] ]; if ( d[u] + 1 != d[e.v] ) continue; f = dfs(e.v, min(a, e.rest) ); if ( f > 0 ) { e.rest -= f; edges[ G[u][i]^1 ].rest += f; flow += f; a -= f; if ( a == 0 )break; } } return flow; } long long maxflow(int _s, int _t){ s = _s, t = _t; long long flow = 0, mf; while ( bfs() ){ fill(cur,cur+n,0); while ( (mf = dfs(s, INF)) ) flow += mf; } return flow; } };
# Maximum-flow
題
'\n'
好欸講完了
flow
By wen Ian
flow
- 324