最小割的 Gomory-Hu 树算法
字数 1909 2025-11-27 09:30:55

最小割的 Gomory-Hu 树算法

题目描述
给定一个无向连通图 \(G = (V, E)\),每条边有一个非负容量(权重),要求构建一棵 Gomory-Hu 树(也称为割树)。这棵树具有以下性质:

  1. 树的节点与原图节点相同(即 \(V\) 是树的节点集)。
  2. 对于树中任意一条边 \(e\),若移除 \(e\),树会分裂成两个连通分支,对应原图的一个最小割。
  3. 对于任意一对节点 \(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)  

(容量为边的权重)

递归过程

  1. 初始集合 \(S = \{1,2,3,4\}\),选 \(s=1, t=4\)
    • 最大流计算得最小割 \(A=\{1,2,3\}, B=\{4\}\),容量为 4(割边为 (3,4))。
    • 割树添加边 (3,4) 容量 4。
  2. 递归处理 \(A=\{1,2,3\}\)(收缩 B 为超级节点)。
    • \(s=1, t=3\),最大流得最小割 \(A'=\{1,2\}, B'=\{3\}\),容量为 3(割边为 (2,3))。
    • 割树添加边 (2,3) 容量 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 树将原图的所有最小割信息编码成一棵树,通过递归划分和最大流计算逐步构建,是解决最小割查询的高效数据结构。

最小割的 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 节点的图: (容量为边的权重) 递归过程 : 初始集合 \( 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。 最终割树为: 任意两点间最小割可通过树上路径最小边容量得到。 4. 关键点说明 收缩操作 :递归时收缩另一部分节点,确保子图的最小割与原图一致。 复杂度 :共需 \( n-1 \) 次最大流计算(\( n = |V| \)),若用 Dinic 算法(复杂度 \( O(V^2E) \)),总复杂度为 \( O(V^3E) \),但实际优化后可达 \( O(V^2 \cdot \text{maxflow}) \)。 应用 :割树一旦构建,任意两点最小割查询可在 \( O(\log V) \) 时间内完成(使用树上 RMQ)。 总结 Gomory-Hu 树将原图的所有最小割信息编码成一棵树,通过递归划分和最大流计算逐步构建,是解决最小割查询的高效数据结构。