算法导论 24.2 Exercises 答案

24.2-1

对于 u 的所有非出边,根据定义,都有 c(u,v)=0,因此 f(u,v)=c(u,v)=0,也就是有 vVl(u)f(u,v)=vVf(u,v)

对于 u 的所有非入边,根据定义,都有 c(v,u)=0,因此 f(v,u)=c(v,u)=0,也就是有 vVe(u)f(v,u)=vVf(v,u)

对于 u 的所有非关联边,无论之后的流变化如何,根据定义,都有 c(v,u)=c(u,v)=0,因此 f(v,u)=f(v,u)=0,也就是有 vVl(u)Ve(u)f(v,u)=vVf(v,u),vVl(u)Ve(u)f(u,v)=vVf(u,v)

因此,最终有

vVl(u)f(u,v)vVe(u)f(v,u)+vVl(u)Ve(u)f(u,v)vVl(u)Ve(u)f(v,u)=vVf(u,v)vVf(v,u)+vVf(u,v)vVf(v,u)=(vVf(u,v)vVf(v,u))+(vVf(u,v)vVf(v,u))=0

24.2-2

S 中的节点到 T 中的节点的所有边如下:

efc(s,v1)1116(v2,v1)14(v4,v3)77(v4,t)44

T 中的节点到 S 中的节点的所有边如下:

efc(v3,v2)49

因此,切割 (S,T) 11+1+7+44=19,容量为 16+4+7+5=31

24.2-3

接下里将使用残余网络来表示这个流网络。一开始残余网络如下:

随后运行 BFS,找到了一条增广路径 (s,v1,v3,t),其流量值为 12。由此可以对残余网络进行更新:

随后找到了一条增广路径 (s,v2,v4,t),其流量值为 4。由此可以对残余网络进行更新:

最后找到了一条增广路径 (s,v2,v4,v3,t),其流量值为 7。由此可以对残余网络进行更新:

此后,再也不存在增广路径,因此最大流 |f|=23

24.2-4

S={s,v1,v2,v4},T={v3,t} 为所求。图 24.6 (c) 中路径上的边 (v1,v2) 抵消了图 24.6 (b) 所传输的流;图 24.6 (c) 中路径上的边 (v2,v3) 抵消了图 24.6 (a) 所传输的流。

24.2-5

G=(V,E) 是一个具有多源点多汇点的流网络,并令 S={s1,s2,,sm},T={t1,t2,,tn},即 S G 中的所有源点,T G 中的所有原点。由于 ST=,(ST)V,因此可以构造出一个在图 G 上的切割 (S,T),使得 SS,TT。由于 G 的网络容量是有限的,即 (u,v)E,c(u,v)<,因此横跨切割 (S,T) 中的所有边的容量都是有限的,那么切割 (S,T) 的容量 c(S,T) 是有限的。

这个流网络转换后,那么令新流网络为 G1=(V1,E1),其中 V1=V{s,t},并且 s 是超级源点,t 是超级汇点。那么对流网络构造切割 (S1,T1) 满足 S1=S{s},T1=T{t},那么可见,图 G1 上切割 (S1,T1) 的容量 c(S1,T1) c(S,T) 是相等的的(因为横跨这两个切割的都是相同的边),因此按照推论 26.5,G1 中的所有流都受限于 c(S1,T1),即任何一个流的值都是有限的。

24.2-6

思路和第 24.1 节时构造超级源点和超级汇点相似。令 G=(V,E) 是题目所提供的流网络,并令 S={s1,s2,,sm},T={t1,t2,,tn},即 S G 中的所有源点,T G 中的所有原点。

那么令新转化后的流网络为 G=(V,E),其中 V=V{s,t},并且 s 是超级源点,t 是超级汇点。并且 (u,v)E,(u,v)E 均成立,c(u,v)=c(u,v)。对于 siS,(s,si)E,并且有 c(s,si)=pi;对于 tiT,(ti,t)E,并且有 c(t1,t)=qi

最终所给定的流网络 G 和容量函数 c 为所求。

24.2-7

令这条简单路径 p 表示为 v1,v2,,vm,其中 v1=s,vm=t

首先证明容量限制。按照 cf(p) 的定义,可以得出 (u,v)p,cf(p)cf(u,v)。因此,对于 (u,v)p,fp(u,v)=cf(p)cf(u,v)。由于边的容量是正数,因此可以得出 cf(p)>0。也就是说,fp(u,v)0。对于 (u,v)p,都有 fp(u,v)=0。因此容量限制得证。

接下来证明流量守恒。vp,由于增广路径 p 不经过 v,因此流入 v 的流量和与流出 v 的流量和均为 0,因此 v 处满足流量守恒。vp{s,t},仅有一条边流入 v 和一条边流出 v,并且它们的流量值均为 cf(p),因此 v 处满足流量守恒。

fp Gf 中的一个流。对于 s,仅有一条边从它流出,其大小为 cf(p),因此 |fp|=cf(p)>0

24.2-8

可见,算法 FORD-FULKERSON 的第 3 行是求解了一条增广路径,即从 s t 的简单路径。由于这是一条以 s 为起点的简单路径,因此这条路径不可能从某处重新到达 s,因此残余网络中,指向 s 的反向边是不必要的,它不会影响第 3 行的求解增广路径求取算法。因此原结论成立。

24.2-9

如此增广后的 ff 将不是 G 中的一个流。不过,ff 仍然满足流量守恒,因为方程 24.6 的推导仅仅依赖于 f 本身的定义,根据题目 24.2-1 的进一步形式化证明可知,ff 仍然满足流量守恒。

接下来说明 ff 不满足容量限制。令 G=(V,E),V={s,t},E={(s,t)},c(s,t)=1。如图所示:

1
s
t

那么,令 f,f 是两个流,其中 f(s,t)=f(s,t)=1,那么可以计算出 (ff)(s,t)=f(s,t)+f(s,t)f(t,s)=1+10=2>c(s,t),从而违反了容量限制。

24.2-10

首先求出流网络 G=(V,E) 的其中一个最大流 f。那么令 c(u,v)=f(u,v)。并且,如果 c(u,v)>0,那么 (u,v)E。由此可知,EE

这个算法将进行多次迭代,每次迭代的过程中,找到 E c 值最小的边 (u,v),并且通过在 G=(V,E) 上对 u 进行反向 BFS,对 v 进行正向 BFS,找到一条路径 p:suvt。可见,p 是一条增广路径,并存入数组中,接下来令 cf(p)=c(u,v)。那么对 p 中的所有边,都减去值 cf(p)。这轮迭代结束后,边 (u,v) 必定从 E 中删除。因此,这个算法最多迭代 |E||E| 次,也就是说,最多只有 |E| 条增广路径。

大致过程由 AUGMENTING-PATHS-BOUNDS 给出,其迭代轮数至多为 |E| 轮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
AUGMENTING-PATHS-BOUNDS(G, s, t)
Let P be a new array
Let E' be a new set
FORD-FULKERSON(G, s, t)
for each edge (u, v) ∈ G.E
if (u, v).f > 0
(u, v).c' = (u, v).f
INSERT(E', (u, v))
while E' != ∅
let (u, v) be the edge s.t. (u, v).c' is minimum in E'.
run BFS twice (forward and back) to get the path p from s to t through (u,v)
INSERT(P, p)
c' = (u, v).c'
for each edge (u, v) ∈ E'
(u, v).c' = (u, v).c' - c'
if (u, v).c' == 0
DELETE(E', (u, v))
return E

24.2-11

首先,一个无向图 G=(V,E) 不连通意味着:uV,vV,使得从 u 节点不可到达 v 节点。因此,我们可以随机选定 V 中的一个节点作为源点 s,枚举所有 tV{s} 作为汇点,并且将 G 中的每一条无向边都替换成一对容量均为 1 的反平行边。接下来只需要对这个构造出来的流网络求解最大流(也就是这个流网络的最小割),那么求出来的值中,最小的一个恰好为答案。具体过程由 EDGE-CONNECTIVITY 给出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
EDGE-CONNECTIVITY(G)
Let V, E be new sets
V = G.V
select vertex s ∈ G.V randomly
for each edge (u, v) ∈ G.E
Let x be a new vertex
INSERT(V, x)
INSERT(E, (u, v))
(u, v).c_f = 1
INSERT(E, (v, x))
(v, x).c_f = 1
INSERT(E, (x, u))
(x, u).c_f = 1
edge-connectivity = |G.V| - 1
for each vertex t ∈ G.V - {s}
Let G' = (V, E) be a new flow net work
FORD-FULKERSON(G', s, t)
edge-connectivity = min{edge-connectivity, |f|}
return edge-connectivity

我们构造了 |V|1 个流网络,每个流网络一共有 |V|+|E|=O(V+E) 个节点,一共有 3|E|=O(E) 条边。因此如上算法为所求。

24.2-12

由于所有增广路径都是从 s 开始的,因此如果存在一条边 (v,s),使得 f(v,s)=1,那么这意味着节点 s 在某个环上(也就是说,边 (v,s) 也在环上)。我们可以考虑对流 f 进行 DFS,处理出这个环,并且将这个环上的所有边的流大小减去 1,得到的新流 f 则是所求流。

不难证明所求流 f 满足容量限制,因为环上的所有边的流大小都超过 1,将它们都减去 1 不会使得流大小变成负数。流量守恒也不难证明,因为这个环上的所有节点,减去的流入流量和流出流量都为 1,因此由于原来的流 f 满足流量守恒,f 也满足流量守恒;对于 s 也如此,因此有 |f|=|f|

整个具体过程由 SIMPLIFY-FLOAT-1 给出,由于是对一次 DFS 进行修改,因此其时间复杂度为 O(E)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SIMPLIFY-FLOAT-DFS(G, s, u)
u.color = GRAY
for each vertex v in G.Adj[u]
if (u, v).f > 0
if v.color == WHITE
v.π = u
SIMPLIFY-FLOAT-DFS(G, s, v)
else if v.color == GRAY and v == s and (u, s).f == 1
(u, s).f = (u, s).f - 1
z = u
while z != NIL
(z.p, z).f = (z.p, z).f - 1
z = z.p
exit // 算法结束,从此退出。
u.color = BLACK

SIMPLIFY-FLOAT-1(G, s, t)
for each vertex u ∈ G.V
u.color = WHITE
u.π = NIL
SIMPLIFY-FLOAT-DFS(G, s, s)

24.2-13

假设对流网络 G=(V,E) 所有边的容量 c 都加上一个足够小的常数 ϵ 得到 c,那么对于 G 中的以容量函数 c 得到的每一个最小割 (S,T),如果其容量值为 C,那么以容量函数 c 为计算的切割 (S,T) 的容量为 C+ϵMS,T,其中 MS,T 是从 S 中的节点指向 T 中的节点的边数。那么,以容量函数 c 运行最大流算法后,在残余网络 Gf 中,从 s 可达的节点集合为 S,其余节点在 T 中,那么切割 (S,T) 为以容量函数 c 所求的最小割,并且切割的边数最小。

这个常数 ϵ 必须足够小,以至于对最大流的值产生的影响是微不足道的(产生的影响小于 1 个单位的流)。因此,ϵ=1|E|+1 是一个合适的取值,哪怕所有边都做出了贡献,对最大流的贡献总共也只有 |E||E|+1,不超过 1

当然,为了确保流的容量仍然是整数,我们可以考虑对容量函数 c 进行放缩。将 c 所有的容量全部都扩大到原来的 |E|+1 倍,那么求出来的最大流也是原来的 |E|+1 倍。接下来再对所有边容量都加上 1,运行最大流算法后,从 s 可达的节点集合为 S,其余节点在 T 中,切割 (S,T) 为所求。更正式的定义,则是 (u,v)E,取 c(u,v)=c(u,v)(|E|+1)+1

这个算法的过程由 MINIMIN-CUT-MINIMUM-EDGES 给出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
MINIMIN-CUT-MINIMUM-EDGES(G, s, t)
for each edge (u, v) ∈ G.E
(u, v).{c'_f} = (u, v) * (|G.E| + 1) + 1
run FORD-FULKERSON(G, s, t) using c_'f as capacity.
let E, S, T be a new set
for each edge (u, v) ∈ G.E
if (u, v).f > -
INSERT(E, (u, v))
let G' = (G.V, E) be a new graph
BFS(G', s)
for each vertex u ∈ G.V
if u.color == BLACK
INSERT(S, u)
else
INSERT(T, u)
return (S, T)