说明
在网络流相关问题中,在流网络(原网络) G = ( V , E ) G=(V, E) G = ( V , E ) 中不考虑反向边
只有在任意流 ∀ f \forall f ∀ f 所对应的残量网络 G f G_f G f 中,才考虑反向边
流网络
一个源点 s s s 和一个汇点 t t t
边集合 E E E 中包含一条边 ( u , v ) (u, v) ( u , v ) ,则不存在反向边 ( v , u ) (v, u) ( v , u )
边的容量值为 c ( u , v ) c(u, v) c ( u , v ) ,流量为 f ( u , v ) f(u, v) f ( u , v )
容量限制∀ u , v ∈ V , 0 ⩽ f ( u , v ) ⩽ c ( u , v ) \forall u, v \in V, \quad 0 \leqslant f(u, v) \leqslant c(u, v)
∀ u , v ∈ V , 0 ⩽ f ( u , v ) ⩽ c ( u , v )
流量守恒∀ u ∈ V − { s , t } , ∑ v ∈ V f ( v , u ) = ∑ v ∈ V f ( u , v ) \forall u \in V - \{s, t\}, \quad \sum_{v \in V} f(v, u) = \sum_{v \in V} f(u, v)
∀ u ∈ V − { s , t } , v ∈ V ∑ f ( v , u ) = v ∈ V ∑ f ( u , v )
特别地,如果 ( u , v ) ∉ E , f ( u , v ) = 0 (u, v) \notin E, f(u, v) = 0 ( u , v ) ∈ / E , f ( u , v ) = 0
流∣ f ∣ = ∑ v ∈ V f ( s , v ) − ∑ v ∈ V f ( v , s ) |f| = \sum_{v \in V} f(s, v) - \sum_{v \in V} f(v, s)
∣ f ∣ = v ∈ V ∑ f ( s , v ) − v ∈ V ∑ f ( v , s )
Ford-Fulkerson 方法
初始化流为 f = 0 f = 0 f = 0
while \textbf{while} while 在残量网络 G f 中存在一条增广路径 p \text{在残量网络 } G_f \ \text{中存在一条增广路径} \ p 在残量网络 G f 中存在一条增广路径 p
沿着 p 增加流 f \text{沿着} \ p \ \text{增加流} \ f 沿着 p 增加流 f
return f \textbf{return} \ f return f
残量网络
c f ( u , v ) = { c ( u , v ) − f ( u , v ) 如果 ( u , v ) ∈ E f ( v , u ) 如果 ( v , u ) ∈ E 0 其他 c_f(u, v) = \begin{cases}
c(u, v) - f(u, v) && \text{如果} \ (u, v) \in E \\
f(v, u) && \text{如果} \ (v, u) \in E \\
0 && \text{其他}
\end{cases}
c f ( u , v ) = ⎩ ⎪ ⎪ ⎨ ⎪ ⎪ ⎧ c ( u , v ) − f ( u , v ) f ( v , u ) 0 如果 ( u , v ) ∈ E 如果 ( v , u ) ∈ E 其他
f ′ f' f ′ 为残量网络中的一个流,定义 f ′ ↑ f f' \uparrow f f ′ ↑ f 为流 f ′ f' f ′ 对 f f f 的递增
( f ↑ f ′ ) ( u , v ) = { f ( u , v ) + f ′ ( u , v ) − f ′ ( v , u ) 若 ( u , v ) ∈ E 0 其他 (f \uparrow f')(u, v) = \begin{cases}
f(u, v) + f'(u, v) - f'(v, u) && \text{若} (u, v) \in E \\
0 && \text{其他}
\end{cases}
( f ↑ f ′ ) ( u , v ) = { f ( u , v ) + f ′ ( u , v ) − f ′ ( v , u ) 0 若 ( u , v ) ∈ E 其他
引理1
G ( V , E ) G(V, E) G ( V , E ) 为流网络,设 f f f 为 G G G 中的一个流,G f G_f G f 为对应的残量网络
f ′ f' f ′ 为 G f G_f G f 中的一个流,那么 f ↑ f ′ f \uparrow f' f ↑ f ′ 为 G G G 中的一个流
并且 ∣ f ↑ f ′ ∣ = ∣ f ∣ + ∣ f ′ ∣ |f \uparrow f'| = |f| + |f'| ∣ f ↑ f ′ ∣ = ∣ f ∣ + ∣ f ′ ∣
容量限制,f ′ ( v , u ) ⩽ c f ( v , u ) = f ( u , v ) f'(v, u) \leqslant c_f(v, u) = f(u, v) f ′ ( v , u ) ⩽ c f ( v , u ) = f ( u , v ) ( f ↑ f ′ ) ( u , v ) = f ( u , v ) + f ′ ( u , v ) − f ′ ( v , u ) ⇒ f ′ ( v , u ) ⩽ f ( u , v ) ⩾ f ( u , v ) + f ′ ( u , v ) − f ( u , v ) = f ′ ( u , v ) ⩾ 0 \begin{aligned}
(f \uparrow f')(u, v) &= f(u, v) + f'(u, v) - f'(v, u) \xRightarrow{f'(v,u) \leqslant f(u,v)} \\
&\geqslant f(u, v) + f'(u, v) - f(u, v) = f'(u, v) \geqslant 0
\end{aligned}
( f ↑ f ′ ) ( u , v ) = f ( u , v ) + f ′ ( u , v ) − f ′ ( v , u ) f ′ ( v , u ) ⩽ f ( u , v ) ⩾ f ( u , v ) + f ′ ( u , v ) − f ( u , v ) = f ′ ( u , v ) ⩾ 0
( f ↑ f ′ ) ( u , v ) = f ( u , v ) + f ′ ( u , v ) − f ′ ( v , u ) ⇒ f ′ ( v , u ) ⩾ 0 ⩽ f ( u , v ) + f ′ ( u , v ) ⩽ f ( u , v ) + c f ( u , v ) = f ( u , v ) + c ( u , v ) − f ( u , v ) = c ( u , v ) \begin{aligned}
(f \uparrow f')(u, v) &= f(u, v) + f'(u, v) - f'(v, u) \xRightarrow{f'(v,u) \geqslant 0} \\
&\leqslant f(u, v) + f'(u, v) \leqslant f(u, v) + c_f(u, v) \\
&= f(u, v) + c(u, v) - f(u, v) = c(u, v)
\end{aligned}
( f ↑ f ′ ) ( u , v ) = f ( u , v ) + f ′ ( u , v ) − f ′ ( v , u ) f ′ ( v , u ) ⩾ 0 ⩽ f ( u , v ) + f ′ ( u , v ) ⩽ f ( u , v ) + c f ( u , v ) = f ( u , v ) + c ( u , v ) − f ( u , v ) = c ( u , v )
流量守恒,对于所有节点 u ∈ V − { s , t } u \in V - \{s, t\} u ∈ V − { s , t } ∑ v ∈ V ( f ↑ f ′ ) ( u , v ) = ∑ v ∈ V ( f ( u , v ) + f ′ ( u , v ) − f ′ ( v , u ) ) = ∑ v ∈ V f ( u , v ) + ∑ v ∈ V f ′ ( u , v ) − ∑ v ∈ V f ′ ( v , u ) ⇒ 流量守恒 = ∑ v ∈ V f ( u , v ) + ∑ v ∈ V f ′ ( v , u ) − ∑ v ∈ V f ′ ( u , v ) = ∑ v ∈ V ( f ( v , u ) + f ′ ( v , u ) − f ′ ( u , v ) ) = ∑ v ∈ V ( f ↑ f ′ ) ( v , u ) \begin{aligned}
\sum_{v \in V}(f \uparrow f')(u, v) &=
\sum_{v \in V} \left( f(u, v) + f'(u, v) - f'(v, u) \right) \\
&= \sum_{v \in V} f(u, v) + \sum_{v \in V} f'(u, v) - \sum_{v \in V} f'(v, u) \xRightarrow{\text{流量守恒}} \\
&= \sum_{v \in V} f(u, v) + \sum_{v \in V} f'(v, u) - \sum_{v \in V} f'(u, v) \\
&= \sum_{v \in V} \left( f(v, u) + f'(v, u) - f'(u, v) \right) \\
&= \sum_{v \in V} (f \uparrow f')(v, u)
\end{aligned}
v ∈ V ∑ ( f ↑ f ′ ) ( u , v ) = v ∈ V ∑ ( f ( u , v ) + f ′ ( u , v ) − f ′ ( v , u ) ) = v ∈ V ∑ f ( u , v ) + v ∈ V ∑ f ′ ( u , v ) − v ∈ V ∑ f ′ ( v , u ) 流量守恒 = v ∈ V ∑ f ( u , v ) + v ∈ V ∑ f ′ ( v , u ) − v ∈ V ∑ f ′ ( u , v ) = v ∈ V ∑ ( f ( v , u ) + f ′ ( v , u ) − f ′ ( u , v ) ) = v ∈ V ∑ ( f ↑ f ′ ) ( v , u )
流量计算
V 1 = { v : ( s , v ) ∈ E } V_1 = \{v : (s, v) \in E\} V 1 = { v : ( s , v ) ∈ E } 表示从源点 s s s 流出的流量,流量能到达的点的集合
V 2 = { v : ( v , s ) ∈ E } V_2 = \{v : (v, s) \in E\} V 2 = { v : ( v , s ) ∈ E } 表示流回源点 s s s 的流量,这些流量经过的点集∣ f ↑ f ′ ∣ = ∑ v ∈ V 1 ( f ↑ f ′ ) ( s , v ) − ∑ v ∈ V 2 ( f ↑ f ′ ) ( v , s ) |f \uparrow f'| = \sum_{v \in V_1} (f \uparrow f')(s, v) - \sum_{v \in V_2} (f \uparrow f')(v, s)
∣ f ↑ f ′ ∣ = v ∈ V 1 ∑ ( f ↑ f ′ ) ( s , v ) − v ∈ V 2 ∑ ( f ↑ f ′ ) ( v , s )
∣ f ↑ f ′ ∣ = ∑ v ∈ V 1 ( f ( s , v ) + f ′ ( s , v ) − f ′ ( v , s ) ) − ∑ v ∈ V 2 ( f ( v , s ) + f ′ ( v , s ) − f ′ ( s , v ) ) = ∑ v ∈ V 1 f ( s , v ) + ∑ v ∈ V 1 f ′ ( s , v ) − ∑ v ∈ V 1 f ′ ( v , s ) − ∑ v ∈ V 2 f ( v , s ) − ∑ v ∈ V 2 f ′ ( v , s ) + ∑ v ∈ V 2 f ′ ( s , v ) = ∑ v ∈ V 1 f ( s , v ) − ∑ v ∈ V 2 f ( v , s ) + ( ∑ v ∈ V 1 f ′ ( s , v ) + ∑ v ∈ V 2 f ′ ( s , v ) ) − ( ∑ v ∈ V 1 f ′ ( v , s ) + ∑ v ∈ V 2 f ′ ( v , s ) ) = ( ∑ v ∈ V 1 f ( s , v ) − ∑ v ∈ V 2 f ( v , s ) ) + ( ∑ v ∈ V 1 ∪ V 2 f ′ ( s , v ) − ∑ v ∈ V 1 ∪ V 2 f ′ ( v , s ) ) \begin{aligned}
|f \uparrow f'| &= \sum_{v \in V_1} (f(s, v) + f'(s, v) - f'(v,s)) - \sum_{v\in V_2}(f(v,s) + f'(v,s) - f'(s, v)) \\
&= \sum_{v \in V_1}f(s, v) + \sum_{v \in V_1}f'(s, v) - \sum_{v \in V_1}f'(v, s) \\
&\quad - \sum_{v \in V_2}f(v, s) - \sum_{v \in V_2}f'(v,s) + \sum_{v \in V_2} f'(s, v) \\
&= \sum_{v \in V_1} f(s, v) - \sum_{v \in V_2}f(v,s) \\
&\quad + \left(\sum_{v \in V_1}f'(s, v) + \sum_{v \in V_2}f'(s, v) \right) - \left(\sum_{v \in V_1}f'(v, s) + \sum_{v \in V_2}f'(v,s) \right) \\
&= \left( \sum_{v \in V_1}f(s, v) - \sum_{v \in V_2}f(v,s) \right) + \left( \sum_{v \in V_1 \cup V_2} f'(s, v) - \sum_{v \in V_1 \cup V_2} f'(v,s) \right)
\end{aligned}
∣ f ↑ f ′ ∣ = v ∈ V 1 ∑ ( f ( s , v ) + f ′ ( s , v ) − f ′ ( v , s ) ) − v ∈ V 2 ∑ ( f ( v , s ) + f ′ ( v , s ) − f ′ ( s , v ) ) = v ∈ V 1 ∑ f ( s , v ) + v ∈ V 1 ∑ f ′ ( s , v ) − v ∈ V 1 ∑ f ′ ( v , s ) − v ∈ V 2 ∑ f ( v , s ) − v ∈ V 2 ∑ f ′ ( v , s ) + v ∈ V 2 ∑ f ′ ( s , v ) = v ∈ V 1 ∑ f ( s , v ) − v ∈ V 2 ∑ f ( v , s ) + ( v ∈ V 1 ∑ f ′ ( s , v ) + v ∈ V 2 ∑ f ′ ( s , v ) ) − ( v ∈ V 1 ∑ f ′ ( v , s ) + v ∈ V 2 ∑ f ′ ( v , s ) ) = ( v ∈ V 1 ∑ f ( s , v ) − v ∈ V 2 ∑ f ( v , s ) ) + ( v ∈ V 1 ∪ V 2 ∑ f ′ ( s , v ) − v ∈ V 1 ∪ V 2 ∑ f ′ ( v , s ) )
∣ f ↑ f ′ ∣ = ∣ f ∣ + ∣ f ′ ∣ |f \uparrow f'| = |f| + |f'|
∣ f ↑ f ′ ∣ = ∣ f ∣ + ∣ f ′ ∣
增广路径
沿着增广路径走,注意 G f G_f G f 中反向边流量增加
一条增广路径 p p p 能够给 G G G 每条边增加的流量最大值为路径 p p p 的残存容量
c f ( p ) = min { c f ( u , v ) : ( u , v ) 属于路径 p } c_f(p) = \min \{c_f(u, v) : (u, v)\ \text{属于路径} \ p \}
c f ( p ) = min { c f ( u , v ) : ( u , v ) 属于路径 p }
引理
G = ( V , E ) G=(V, E) G = ( V , E ) 为一个流网络,设 f f f 为 G G G 中的一个流,设 p p p 为残量网络 G f G_f G f 中的一条增广路径f p ( u , v ) = { c f ( p ) 若 ( u , v ) 在 p 上 0 其他 f_p(u, v) = \begin{cases}
c_f(p) && \text{若} \ (u, v) \ \text{在} \ p \text{上} \\
0 && \text{其他}
\end{cases}
f p ( u , v ) = { c f ( p ) 0 若 ( u , v ) 在 p 上 其他
f p f_p f p 是残量网络 G f G_f G f 中的一个流,∣ f p ∣ = c f ( p ) > 0 |f_p| = c_f(p) > 0 ∣ f p ∣ = c f ( p ) > 0
流网络的切割
一个流是最大流当且仅当残量网络中不包括任何增广路径
为了证明这个算法的正确性,先引入流网络切割的概念
切割 ( S , T ) (S, T) ( S , T ) 将流网络划分成了 S S S 和 T = V − S T = V-S T = V − S 两个集合
其中满足 s ∈ S s \in S s ∈ S , t ∈ T t \in T t ∈ T
净流量
f ( S , T ) = ∑ u ∈ S ∑ v ∈ T f ( u , v ) − ∑ u ∈ S ∑ v ∈ T f ( v , u ) f(S, T) = \sum_{u \in S} \sum_{v \in T} f(u, v) - \sum_{u \in S} \sum_{v \in T}f(v, u)
f ( S , T ) = u ∈ S ∑ v ∈ T ∑ f ( u , v ) − u ∈ S ∑ v ∈ T ∑ f ( v , u )
割的容量
c ( S , T ) = ∑ u ∈ S ∑ v ∈ T c ( u , v ) c(S, T) = \sum_{u \in S} \sum_{v \in T} c(u, v)
c ( S , T ) = u ∈ S ∑ v ∈ T ∑ c ( u , v )
引理
设 f f f 为流网络 G G G 的一个流,( S , T ) (S, T) ( S , T ) 为流网络的任意切割,则横跨任意切割∀ ( S , T ) \forall \ (S, T) ∀ ( S , T ) 的净流量总相同
f ( S , T ) = ∣ f ∣ f(S, T) = |f| f ( S , T ) = ∣ f ∣
根据流量守恒
∀ u ∈ V − { s , t } \forall \ u \in V- \{s, t\} ∀ u ∈ V − { s , t } ∑ v ∈ V f ( u , v ) − ∑ v ∈ V f ( v , u ) = 0 \sum_{v \in V} f(u, v) - \sum_{v \in V} f(v, u) = 0
v ∈ V ∑ f ( u , v ) − v ∈ V ∑ f ( v , u ) = 0
对 u ∈ S − { s } u \in S - \{s\} u ∈ S − { s } 进行求和∑ u ∈ S − { s } ( ∑ v ∈ V f ( u , v ) − ∑ v ∈ V f ( v , u ) ) = 0 \sum_{u \in S - \{s\}}\left( \sum_{v \in V}f(u, v) - \sum_{v \in V}f(v, u) \right) = 0
u ∈ S − { s } ∑ ( v ∈ V ∑ f ( u , v ) − v ∈ V ∑ f ( v , u ) ) = 0
由 ∣ f ∣ |f| ∣ f ∣ 的定义∣ f ∣ = ∑ v ∈ V f ( s , v ) − ∑ v ∈ V f ( v , s ) + ∑ u ∈ S − { s } ( ∑ v ∈ V f ( u , v ) − ∑ v ∈ V f ( v , u ) ) |f| = \sum_{v \in V} f(s, v) - \sum_{v \in V} f(v, s) + \sum_{u \in S - \{s\}}\left( \sum_{v \in V}f(u, v) - \sum_{v \in V}f(v, u) \right)
∣ f ∣ = v ∈ V ∑ f ( s , v ) − v ∈ V ∑ f ( v , s ) + u ∈ S − { s } ∑ ( v ∈ V ∑ f ( u , v ) − v ∈ V ∑ f ( v , u ) )
展开并且重新组合∣ f ∣ = ∑ v ∈ V f ( s , v ) − ∑ v ∈ V f ( v , s ) + ∑ u ∈ S − { s } ∑ v ∈ V f ( u , v ) − ∑ u ∈ S − { s } ∑ v ∈ V f ( v , u ) = ∑ v ∈ V ( f ( s , v ) + ∑ u ∈ S − { s } f ( u , v ) ) − ∑ v ∈ V ( f ( v , s ) + ∑ u ∈ S − { s } f ( v , u ) ) = ∑ v ∈ V ∑ u ∈ S f ( u , v ) − ∑ v ∈ V ∑ u ∈ S f ( v , u ) \begin{aligned}
|f| &= \sum_{v \in V}f(s, v) - \sum_{v \in V}f(v, s) + \sum_{u \in S - \{s\}}\sum_{v \in V}f(u, v) - \sum_{u \in S - \{s\}} \sum_{v \in V} f(v, u) \\
&= \sum_{v \in V} \left(f(s, v) + \sum_{u \in S - \{s\}}f(u, v) \right) - \sum_{v \in V} \left( f(v, s) + \sum_{u \in S - \{s\}} f(v, u) \right) \\
&= \sum_{v \in V}\sum_{u \in S} f(u, v) - \sum_{v \in V}\sum_{u \in S} f(v, u)
\end{aligned}
∣ f ∣ = v ∈ V ∑ f ( s , v ) − v ∈ V ∑ f ( v , s ) + u ∈ S − { s } ∑ v ∈ V ∑ f ( u , v ) − u ∈ S − { s } ∑ v ∈ V ∑ f ( v , u ) = v ∈ V ∑ ⎝ ⎛ f ( s , v ) + u ∈ S − { s } ∑ f ( u , v ) ⎠ ⎞ − v ∈ V ∑ ⎝ ⎛ f ( v , s ) + u ∈ S − { s } ∑ f ( v , u ) ⎠ ⎞ = v ∈ V ∑ u ∈ S ∑ f ( u , v ) − v ∈ V ∑ u ∈ S ∑ f ( v , u )
将 v ∈ V v \in V v ∈ V 拆点,拆成 ( v ∈ S ) + ( v ∈ T ) (v \in S) + (v \in T) ( v ∈ S ) + ( v ∈ T ) ∣ f ∣ = ∑ v ∈ S ∑ u ∈ S f ( u , v ) + ∑ v ∈ T ∑ u ∈ S f ( u , v ) − ∑ v ∈ S ∑ u ∈ S f ( v , u ) − ∑ v ∈ T ∑ u ∈ S f ( v , u ) = ∑ v ∈ T ∑ u ∈ S f ( u , v ) − ∑ v ∈ T ∑ u ∈ S f ( v , u ) + ( ∑ v ∈ S ∑ u ∈ S f ( u , v ) − ∑ v ∈ S ∑ u ∈ S f ( v , u ) ) \begin{aligned}
|f| &= \sum_{v \in S}\sum_{u \in S}f(u, v) + \sum_{v \in T} \sum_{u \in S}f(u, v) - \sum_{v \in S}\sum_{u \in S}f(v, u) - \sum_{v \in T} \sum_{u \in S}f(v, u) \\
&= \sum_{v \in T} \sum_{u \in S}f(u, v) - \sum_{v \in T} \sum_{u \in S}f(v, u) \\
&\quad + \left( \sum_{v \in S}\sum_{u \in S}f(u, v) - \sum_{v \in S}\sum_{u \in S}f(v, u) \right)
\end{aligned}
∣ f ∣ = v ∈ S ∑ u ∈ S ∑ f ( u , v ) + v ∈ T ∑ u ∈ S ∑ f ( u , v ) − v ∈ S ∑ u ∈ S ∑ f ( v , u ) − v ∈ T ∑ u ∈ S ∑ f ( v , u ) = v ∈ T ∑ u ∈ S ∑ f ( u , v ) − v ∈ T ∑ u ∈ S ∑ f ( v , u ) + ( v ∈ S ∑ u ∈ S ∑ f ( u , v ) − v ∈ S ∑ u ∈ S ∑ f ( v , u ) )
括号中的求和项实际上是一样的,可以消去。由此∣ f ∣ = ∑ u ∈ S ∑ v ∈ T f ( u , v ) − ∑ u ∈ S ∑ v ∈ T f ( v , u ) = f ( S , T ) |f| = \sum_{u \in S} \sum_{v \in T} f(u, v) - \sum_{u \in S} \sum_{v \in T}f(v, u) = f(S, T)
∣ f ∣ = u ∈ S ∑ v ∈ T ∑ f ( u , v ) − u ∈ S ∑ v ∈ T ∑ f ( v , u ) = f ( S , T )
推论
流网络 G G G 中任意流 f f f 的值不能超过 G G G 的任意切割的容量
∣ f ∣ = f ( S , T ) = ∑ u ∈ S ∑ v ∈ T f ( u , v ) − ∑ u ∈ S ∑ v ∈ T f ( v , u ) ⩽ ∑ u ∈ S ∑ v ∈ T f ( u , v ) ⩽ ∑ u ∈ S ∑ v ∈ T c ( u , v ) = c ( S , T ) \begin{aligned}
|f| &= f(S, T) = \sum_{u \in S} \sum_{v \in T}f(u, v) - \sum_{u \in S} \sum_{v \in T}f(v, u) \\
&\leqslant \sum_{u\in S} \sum_{v \in T} f(u, v) \leqslant \sum_{u \in S}\sum_{v \in T}c(u, v) = c(S, T)
\end{aligned}
∣ f ∣ = f ( S , T ) = u ∈ S ∑ v ∈ T ∑ f ( u , v ) − u ∈ S ∑ v ∈ T ∑ f ( v , u ) ⩽ u ∈ S ∑ v ∈ T ∑ f ( u , v ) ⩽ u ∈ S ∑ v ∈ T ∑ c ( u , v ) = c ( S , T )
流网络中最大流的值实际上等于一个最小切割的容量
最大流最小切割定理
设 f f f 为流网络 G = ( V , E ) G=(V, E) G = ( V , E ) 中的一个流,源点为 s s s ,汇点为 t t t ,以下条件等价
f f f 是 G G G 的一个最大流
残量网络 G f G_f G f 中不包括任何增广路径
∣ f ∣ = c ( S , T ) |f|=c(S, T) ∣ f ∣ = c ( S , T ) ,其中 ( S , T ) (S, T) ( S , T ) 是流网络 G G G 的某个切割
证明如下
( 1 ) ⇒ ( 2 ) (1) \Rightarrow (2) ( 1 ) ⇒ ( 2 ) ,这是显然的,因为如果有增广路径 p p p ,那么可以让 ∣ f ∣ ← ∣ f ∣ + ∣ f p ∣ |f| \leftarrow |f| + |f_p| ∣ f ∣ ← ∣ f ∣ + ∣ f p ∣
与 ∣ f ∣ |f| ∣ f ∣ 是最大流矛盾
( 2 ) ⇒ ( 3 ) (2) \Rightarrow (3) ( 2 ) ⇒ ( 3 ) ,G f G_f G f 中没有任何增广路径,也就是说,残量网络 G f G_f G f 不存在任何 s → t s \to t s → t 的路径
不妨令 S = { v ∈ V : 在 G f 中存在一条从 s 到 v 的路径 } , T = V − S S = \{v \in V: \text{在} \ G_f \ \text{中存在一条从} \ s \ \text{到} \ v \ \text{的路径}\}, \quad T = V-S S = { v ∈ V : 在 G f 中存在一条从 s 到 v 的路径 } , T = V − S
显然 s ∈ S , t ∉ S s \in S, \quad t \notin S s ∈ S , t ∈ / S ,因此划分 ( S , T ) (S, T) ( S , T ) 作为流网络 G G G 的一个切割
u ∈ S , t ∈ T u \in S, \quad t \in T u ∈ S , t ∈ T ,也就是说 ( u , v ) ∈ E (u, v) \in E ( u , v ) ∈ E ,必然有 ( u , v ) ∉ E f (u, v) \notin E_f ( u , v ) ∈ / E f
也就是说 c f ( u , v ) = 0 c_f(u, v) = 0 c f ( u , v ) = 0 c f ( u , v ) = { c ( u , v ) − f ( u , v ) 如果 ( u , v ) ∈ E f ( v , u ) 如果 ( v , u ) ∈ E 0 其他 c_f(u, v) = \begin{cases}
c(u, v) - f(u, v) && \text{如果} \ (u, v) \in E \\
f(v, u) && \text{如果} \ (v, u) \in E \\
0 && \text{其他}
\end{cases}
c f ( u , v ) = ⎩ ⎪ ⎪ ⎨ ⎪ ⎪ ⎧ c ( u , v ) − f ( u , v ) f ( v , u ) 0 如果 ( u , v ) ∈ E 如果 ( v , u ) ∈ E 其他
也就是说,有 f ( u , v ) = c ( u , v ) f(u, v) = c(u, v) f ( u , v ) = c ( u , v ) ,并且 f ( v , u ) = 0 f(v, u) = 0 f ( v , u ) = 0
因此f ( S , T ) = ∑ u ∈ S ∑ v ∈ T f ( u , v ) − ∑ v ∈ T ∑ u ∈ S f ( v , u ) = ∑ u ∈ S ∑ v ∈ T c ( u , v ) − ∑ v ∈ T ∑ u ∈ S 0 = c ( S , T ) f(S, T) = \sum_{u \in S}\sum_{v \in T}f(u, v) - \sum_{v \in T}\sum_{u \in S}f(v, u) = \sum_{u\in S} \sum_{v \in T}c(u, v) - \sum_{v \in T} \sum_{u \in S} 0 = c(S, T)
f ( S , T ) = u ∈ S ∑ v ∈ T ∑ f ( u , v ) − v ∈ T ∑ u ∈ S ∑ f ( v , u ) = u ∈ S ∑ v ∈ T ∑ c ( u , v ) − v ∈ T ∑ u ∈ S ∑ 0 = c ( S , T )
( 3 ) ⇒ ( 1 ) (3) \Rightarrow (1) ( 3 ) ⇒ ( 1 )
很显然 ∣ f ∣ ⩽ c ( S , T ) |f| \leqslant c(S, T) ∣ f ∣ ⩽ c ( S , T ) ,∣ f ∣ = c ( S , T ) |f| = c(S, T) ∣ f ∣ = c ( S , T ) 取最大值
Ford-Fulkerson 算法
for ∀ edge ( u , v ) ∈ G . E \textbf{for} \ \forall \text{ edge}(u, v) \in G.E for ∀ edge ( u , v ) ∈ G . E
( u , v ) . f = 0 \quad (u, v).f = 0 ( u , v ) . f = 0
while 在残量网络 G f 存在一条 s → t 的增广路径 p \textbf{while} \ \text{在残量网络} \ G_f \ \text{存在一条} \ s\to t \ \text{的增广路径} \ p while 在残量网络 G f 存在一条 s → t 的增广路径 p
c f ( p ) = min { c f ( u , v ) ( u , v ) ∈ p } \quad c_f(p) = \min \{c_f(u, v) \quad (u, v) \in p\} c f ( p ) = min { c f ( u , v ) ( u , v ) ∈ p }
for ∀ edge ( u , v ) ∈ p \quad \textbf{for} \ \forall \ \text{edge}(u, v) \in p for ∀ edge ( u , v ) ∈ p
if ( u , v ) ∈ E : ( u , v ) . f = ( u , v ) . f + c f ( p ) \quad \quad \textbf{if} \ (u, v) \in E: \quad (u, v).f = (u, v).f + c_f(p) if ( u , v ) ∈ E : ( u , v ) . f = ( u , v ) . f + c f ( p )
else : ( v , u ) . f = ( v , u ) . f − c f ( p ) \quad \quad \textbf{else}: \quad (v, u).f = (v, u).f - c_f(p) else : ( v , u ) . f = ( v , u ) . f − c f ( p )
算法分析
w h i l e \bold{while} w h i l e 循环中,使用 b f s \bold{bfs} b f s 找增广路,时间复杂度为 O ( V + E ) = O ( E ) O(V+E) = O(E) O ( V + E ) = O ( E )
也就是说,每执行一次 w h i l e \bold{while} w h i l e 循环,所需要的时间复杂度为 O ( E ) O(E) O ( E )
最坏情况每次 c f ( p ) = 1 c_f(p) = 1 c f ( p ) = 1 ,每次只增加 1 1 1 ,while \textbf{while} while 循环最坏执行 O ( ∣ f ∣ ) O(|f|) O ( ∣ f ∣ ) 次
时间复杂度为 O ( E ∣ f ∣ ) O(E |f|) O ( E ∣ f ∣ )
Edmonds-Karp 算法
使用 b f s \bold{bfs} b f s 找增广路,选择 s → t s \to t s → t 的最短路径作为增广路
其中每条边的权重为单位距离,δ f ( u , v ) \delta_f(u, v) δ f ( u , v ) 表示残量网络 G f G_f G f 中
s → t s \to t s → t 的最短路径距离,其中每条边的权重为单位距离
时间复杂度 O ( V E 2 ) O(VE^2) O ( V E 2 )
引理
Edmonds-Karp \text{Edmonds-Karp} Edmonds-Karp 算法运行在流网络 G = ( V , E ) G=(V,E) G = ( V , E ) 上,对于所有的节点 v ∈ V − { s , t } v \in V - \{s, t\} v ∈ V − { s , t }
残量网络 G f G_f G f 的最短路径 δ f ( s , v ) \delta_f(s, v) δ f ( s , v ) 随着流量的递增而单调增加
假设存在一个流量递增操作 f → f ′ f \to f' f → f ′ ,对于 G f G_f G f 中的边 ( u , v ) (u, v) ( u , v )
δ f ′ ( s , u ) ⩾ δ f ( s , u ) \delta_{f'} (s, u) \geqslant \delta_f (s, u) δ f ′ ( s , u ) ⩾ δ f ( s , u ) ,但
δ f ′ ( s , v ) < δ f ( s , v ) \delta_{f'} (s, v) < \delta_f (s, v) δ f ′ ( s , v ) < δ f ( s , v )
另外根据 bfs \textbf{bfs} bfs 过程,对于边 E f ′ ( u , v ) E_{f'}(u, v) E f ′ ( u , v ) 我们有
δ f ′ ( s , v ) = δ f ′ ( s , u ) + 1 \delta_{f'}(s, v) = \delta_{f'}(s, u) + 1 δ f ′ ( s , v ) = δ f ′ ( s , u ) + 1
对于 ( u , v ) ∈ E f ′ (u, v) \in E_{f'} ( u , v ) ∈ E f ′ ,那么一定有 ( u , v ) ∉ E f (u, v) \notin E_f ( u , v ) ∈ / E f ,否则的话δ f ( s , v ) ⩽ δ f ( s , u ) + 1 因为 ( u , v ) 是可行势 ⩽ δ f ′ ( s , u ) + 1 = δ f ′ ( s , v ) \begin{aligned}
\delta_{f}(s, v) &\leqslant \delta_{f}(s, u) + 1 \quad \text{因为} (u, v) \text{是可行势} \\
&\leqslant \delta_{f'}(s, u) + 1 = \delta_{f'}(s, v)
\end{aligned}
δ f ( s , v ) ⩽ δ f ( s , u ) + 1 因为 ( u , v ) 是可行势 ⩽ δ f ′ ( s , u ) + 1 = δ f ′ ( s , v )
这与归纳假设矛盾
( u , v ) ∈ E f , ( u , v ) ∉ E f ′ (u, v) \in E_f, \quad (u, v)\notin E_{f'} ( u , v ) ∈ E f , ( u , v ) ∈ / E f ′ ,意味着递增操作增加了 v → u v \to u v → u 的流量,即检查了 E f ( v , u ) E_f(v, u) E f ( v , u )
因为 Edmonds-Karp \text{Edmonds-Karp} Edmonds-Karp 算法沿着最短路径增加流,所以 G f G_f G f 中从 s → u s \to u s → u 最短路径最后检查的边是 ( v , u ) (v, u) ( v , u ) δ f ( s , v ) = δ f ( s , u ) − 1 ⩽ δ f ′ ( s , u ) − 1 = δ f ′ ( s , v ) − 2 \begin{aligned}
\delta_{f}(s, v) &= \delta_{f}(s, u) - 1 \\
&\leqslant \delta_{f'}(s, u) - 1 = \delta_{f'}(s, v)-2
\end{aligned}
δ f ( s , v ) = δ f ( s , u ) − 1 ⩽ δ f ′ ( s , u ) − 1 = δ f ′ ( s , v ) − 2
这个与 δ f ′ ( s , v ) < δ f ( s , v ) \delta_{f'}(s, v) < \delta_{f}(s, v) δ f ′ ( s , v ) < δ f ( s , v ) 矛盾
定理
Edmonds-Karp \text{Edmonds-Karp} Edmonds-Karp 算法执行的流量递增操作总次数为 O ( V E ) O(VE) O ( V E )
在残量网络 G f G_f G f 中,对于增广路径 p p p ,如果 c f ( p ) = c f ( u , v ) c_f(p) = c_f(u, v) c f ( p ) = c f ( u , v ) ,( u , v ) (u, v) ( u , v ) 是增广路径的关键边
(在前面的图中,就是容量为 4 4 4 的那条边)
对于 ∣ E ∣ |E| ∣ E ∣ 中的每条边而言,其成为关键边的次数最多为 ∣ V ∣ / 2 |V|/2 ∣ V ∣ / 2 次
沿着增广路径增加流,关键边从残量网络 G f G_f G f 中消失,它再次成为关键边
只有当 ( u , v ) (u, v) ( u , v ) 网络流量减小,也就是 ( v , u ) (v, u) ( v , u ) 出现在增广路径上的时候,如下图
此时有
δ f ( s , v ) = δ f ( s , u ) + 1 \delta_{f}(s, v) = \delta_{f}(s, u) + 1 δ f ( s , v ) = δ f ( s , u ) + 1
δ f ′ ( s , u ) = δ f ′ ( s , v ) + 1 \delta_{f'}(s, u) = \delta_{f'}(s, v) + 1 δ f ′ ( s , u ) = δ f ′ ( s , v ) + 1
因为 δ f ( s , v ) ⩽ δ f ′ ( s , v ) \delta_{f}(s, v) \leqslant \delta_{f'}(s, v) δ f ( s , v ) ⩽ δ f ′ ( s , v ) ,所以有
δ f ′ ( s , u ) = δ f ′ ( s , v ) + 1 ⩾ δ f ( s , v ) + 1 = δ f ( s , u ) + 2 \delta_{f'}(s, u) = \delta_{f'}(s, v) + 1 \geqslant \delta_{f}(s, v) + 1 = \delta_{f} (s, u) + 2 δ f ′ ( s , u ) = δ f ′ ( s , v ) + 1 ⩾ δ f ( s , v ) + 1 = δ f ( s , u ) + 2
从 ( u , v ) (u, v) ( u , v ) 第一次成为关键边到下一次再成为关键边
( s , u ) (s, u) ( s , u ) 之间的距离至少增加了 2 2 2 个单位,因为 s → u s \to u s → u 最短路径不包括 s , t s, t s , t
所以二者之间的距离最多为 ∣ V ∣ − 2 |V|-2 ∣ V ∣ − 2
因此 ( u , v ) (u, v) ( u , v ) 最多可以再成为关键边 O ( ∣ V ∣ / 2 ) O(|V|/2) O ( ∣ V ∣ / 2 ) 次
关键边的总数为 O ( ∣ E ∣ ⋅ ∣ V ∣ / 2 ) O(|E| \cdot |V|/2) O ( ∣ E ∣ ⋅ ∣ V ∣ / 2 )
算法实现
Acwing2171
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 const int maxn = 1000 + 10, maxm = 20000 + 10; const int inf = 0x3f3f3f3f; int head[maxn], ver[maxm], edges[maxm], ne[maxm], tot = 1, n, m, S, T; int d[maxn], pre[maxn], vis[maxn]; void add(int a, int b, int c) { ver[++tot] = b; edges[tot] = c; ne[tot] = head[a]; head[a] = tot; } bool bfs () { memset(vis, 0, sizeof vis); memset(d, 0, sizeof d); memset(pre, 0, sizeof pre); queue<int> q; vis[S] = 1, d[S] = inf, q.push(S); while (q.size()) { int x = q.front(); q.pop(); for (int i = head[x]; i; i = ne[i]) { int y = ver[i]; if (!vis[y] && edges[i] > 0) { vis[y] = true ; d[y] = min(d[x], edges[i]); pre[y] = i; if (y == T) return true ; q.push(y); } } } return false ; } void EK () { int res = 0; while (bfs()) { res += d[T]; for (int i = T; i != S; i = ver[pre[i] ^ 1]) { int id = pre[i]; edges[id] -= d[T], edges[id ^ 1] += d[T]; } } printf ("%d\n" , res); } int main () { //freopen("input.txt" , "r" , stdin); scanf("%d%d%d%d" , &n, &m, &S, &T); for (int i = 0; i < m; i++) { int a, b, c; scanf("%d%d%d" , &a, &b, &c); add(a, b, c); add(b, a, 0); } // Edmonds karp EK(); }