最小割的 Gomory-Hu 树算法
字数 1909 2025-11-27 09:30:55
最小割的 Gomory-Hu 树算法
题目描述
给定一个无向连通图 \(G = (V, E)\),每条边有一个非负容量(权重),要求构建一棵 Gomory-Hu 树(也称为割树)。这棵树具有以下性质:
- 树的节点与原图节点相同(即 \(V\) 是树的节点集)。
- 对于树中任意一条边 \(e\),若移除 \(e\),树会分裂成两个连通分支,对应原图的一个最小割。
- 对于任意一对节点 \(s\) 和 \(t \,它们在树上的唯一路径中容量最小的边,其容量等于原图中 \( s\) 和 \(t\) 之间的最小割容量。
目标:高效地构造 Gomory-Hu 树,使其能快速回答任意两点间的最小割查询。
解题过程
1. 基本思想
Gomory-Hu 算法通过递归地将图分割成更小的部分,逐步构建割树。核心步骤是:
- 选择当前节点集合中的两个节点作为源点(\(s\))和汇点(\(t\)),计算它们之间的最大流(最小割)。
- 根据最小割将节点划分成两个集合,并在割树中添加一条边连接这两个集合的代表节点。
- 递归处理每个划分后的子图,直到每个集合只剩一个节点。
2. 算法步骤详解
步骤 1:初始化
- 设当前节点集合 \(S = V\)(所有节点),初始时整个图是待处理的区域。
- 割树初始为空(只有节点,无边)。
步骤 2:选择源汇点
- 从当前集合 \(S\) 中任选两个节点 \(s\) 和 \(t\)(通常选择集合中第一个和最后一个节点)。
- 若 \(|S| = 1\),则无需处理,直接返回。
步骤 3:计算最小割
- 在原图 \(G\) 上,以 \(s\) 为源点、\(t\) 为汇点,运行最大流算法(如 Edmonds-Karp 或 Dinic),得到最小割 \((A, B)\),其中 \(s \in A\),\(t \in B\)。
- 最小割的容量记为 \(\lambda(s, t)\)。
步骤 4:添加割树边
- 在割树中,添加一条连接 \(A\) 和 \(B\) 的代表节点的边。
- 若 \(A\) 或 \(B\) 中已有代表节点(来自之前的递归),则直接使用该节点;否则任选一个节点作为代表。
- 边的容量设为 \(\lambda(s, t)\)。
步骤 5:递归处理子图
- 对子图 \(G_A\)(由集合 \(A\) 诱导的子图)和 \(G_B\)(由集合 \(B\) 诱导的子图)分别递归执行步骤 2–5。
- 递归时,需保持原图的边容量,但收缩另一部分节点:
- 处理 \(G_A\) 时,将 \(B\) 收缩为一个超级节点(与 \(A\) 中所有连边保留,容量叠加)。
- 处理 \(G_B\) 时,将 \(A\) 收缩为一个超级节点。
步骤 6:终止条件
- 当每个节点集合大小变为 1 时,递归结束。
3. 示例演示(简化)
考虑一个 4 节点的图:
节点:1, 2, 3, 4
边:(1,2, cap=2), (2,3, cap=3), (3,4, cap=4), (1,3, cap=1)
(容量为边的权重)
递归过程:
- 初始集合 \(S = \{1,2,3,4\}\),选 \(s=1, t=4\)。
- 最大流计算得最小割 \(A=\{1,2,3\}, B=\{4\}\),容量为 4(割边为 (3,4))。
- 割树添加边 (3,4) 容量 4。
- 递归处理 \(A=\{1,2,3\}\)(收缩 B 为超级节点)。
- 选 \(s=1, t=3\),最大流得最小割 \(A'=\{1,2\}, B'=\{3\}\),容量为 3(割边为 (2,3))。
- 割树添加边 (2,3) 容量 3。
- 递归处理 \(A'=\{1,2\}\),选 \(s=1, t=2\),最小割容量为 2(割边为 (1,2))。
- 割树添加边 (1,2) 容量 2。
最终割树为:
1 --2-- 2 --3-- 3 --4-- 4
任意两点间最小割可通过树上路径最小边容量得到。
4. 关键点说明
- 收缩操作:递归时收缩另一部分节点,确保子图的最小割与原图一致。
- 复杂度:共需 \(n-1\) 次最大流计算(\(n = |V|\)),若用 Dinic 算法(复杂度 \(O(V^2E)\)),总复杂度为 \(O(V^3E)\),但实际优化后可达 \(O(V^2 \cdot \text{maxflow})\)。
- 应用:割树一旦构建,任意两点最小割查询可在 \(O(\log V)\) 时间内完成(使用树上 RMQ)。
总结
Gomory-Hu 树将原图的所有最小割信息编码成一棵树,通过递归划分和最大流计算逐步构建,是解决最小割查询的高效数据结构。