最小生成树问题(Reverse-Delete 算法)
题目描述
给定一个连通的无向图 \(G = (V, E)\),其中每条边 \(e\) 都有一个正实数权重 \(w(e)\)。我们需要找到一个生成树 \(T\),它是 \(G\) 的一个连通、无环且包含所有顶点的子图,使得 \(T\) 中所有边的总权重最小。这个生成树被称为最小生成树(Minimum Spanning Tree, MST)。
Reverse-Delete 算法是求解此问题的另一种经典方法。其核心思想是逆向应用贪心策略:从原图 \(G\) 开始,按照权重从大到小的顺序考虑每条边,如果不破坏图的连通性,就删除这条边,直到剩下 \(|V| - 1\) 条边,这些边就构成了一个最小生成树。
解题过程
我们将从基本原理出发,逐步推导出完整的算法过程。
步骤1:理解算法的理论基础
Kruskal 算法和 Prim 算法是“正向”贪心算法:从一个空的边集开始,总是添加当前可选的最小的、不构成环的边,直到形成生成树。
Reverse-Delete 算法是它们的“对偶”或“逆向”版本。它的关键在于一个事实:对于一个连通图,删除某条边会破坏连通性,当且仅当该边是当前图的桥。这里的“桥”是指在当前剩余的子图中,删除该边会导致图不再连通。
算法步骤如下:
- 从包含所有边和顶点的原图 \(G\) 开始。
- 将图中的所有边按权重从大到小排序。
- 按排序后的顺序,依次检查每条边 \(e\):
a. 从当前图中临时移除边 \(e\)。
b. 检查移除 \(e\) 后,图是否仍然连通。
c. 如果仍然连通,说明 \(e\) 不是当前图的桥,可以永久删除它,因为它不在任何“必须保留”的边集中。
d. 如果不再连通,说明 \(e\) 是当前图的桥,是保持连通所必需的,必须将其加回(即保留它)。 - 当剩余的边数恰好等于 \(|V| - 1\) 时,算法终止。此时剩余的边构成一个最小生成树。
步骤2:算法正确性分析(理解为何是贪心且最优的)
我们可以通过与 Kruskal 算法对比来理解其正确性。Kruskal 算法每次选择可加入的最小边,遵循“切割性质”:对于图的任意一个切割(将顶点分成两个非空集合),横跨这个切割的最小权重边必然属于某个最小生成树。
Reverse-Delete 算法遵循“环性质”:对于图中的任意一个环,环上权重最大的边必然不属于任何最小生成树。
证明(环性质):
- 假设边 \(e\) 是环 \(C\) 上权重最大的边,且 \(e\) 属于某个最小生成树 \(T\)。
- 从 \(T\) 中移除 \(e\),会将 \(T\) 分成两棵子树。由于 \(e\) 是环的一部分,环上必然存在另一条边 \(f\) (\(f \neq e\)) 连接这两棵子树。
- 由于 \(w(e) \ge w(f)\),将 \(e\) 从 \(T\) 中移除并加入 \(f\),会得到一棵新的生成树 \(T' = T - \{e\} + \{f\}\)。
- \(T'\) 的总权重 \(w(T') = w(T) - w(e) + w(f) \le w(T)\)。因为 \(w(T)\) 是最小的,所以 \(w(T') = w(T)\),即 \(T'\) 也是一个最小生成树,但 \(T'\) 不包含 \(e\)。因此,环上最大边 \(e\) 总可以被替换掉而不增加总权重,所以必然存在一个不包含 \(e\) 的最小生成树。
Reverse-Delete 算法正是基于此:当我们按权重从大到小检查边 \(e\) 时,如果删除它后图仍然连通,就意味着当前图中存在另一条连接 \(e\) 两端点的路径(即 \(e\) 位于某个环上)。根据环性质,这条权重较大的边 \(e\) 可以安全地从候选边集中删除(即不存在包含它的最小生成树)。
步骤3:算法伪代码与数据结构
Reverse-Delete-MST(G, w):
输入:连通无向图 G = (V, E),边权重函数 w
输出:最小生成树 T 的边集
1. T = E // 初始时,T 包含所有边
2. 将 T 中的边按权重 w(e) 从大到小排序
3. for 按排序顺序的每一条边 e in T:
4. 从 T 中临时移除 e: T' = T \ {e}
5. 以 T' 为边集,检查图 (V, T') 是否连通
6. if (V, T') 是连通的:
7. T = T' // 永久删除 e
8. else:
9. // 不连通,说明 e 是桥,必须保留,什么也不做(e 已经在 T 中)
10. // 循环可以提前终止:当 |T| == |V| - 1 时
11. return T
关键操作在于第5步的连通性检查。这通常通过深度优先搜索(DFS)或广度优先搜索(BFS)在子图 \((V, T')\) 上从任意一个顶点开始遍历来完成。如果一次遍历能访问所有 \(|V|\) 个顶点,则图连通。
步骤4:复杂度分析
- 排序:对所有 \(|E|\) 条边排序,时间复杂度为 \(O(|E| \log |E|)\)。
- 主循环:最坏情况下需要检查每一条边,共 \(|E|\) 次迭代。
- 连通性检查:每次检查都需要在最多有 \(|E|\) 条边的图上进行一次 DFS/BFS,其复杂度为 \(O(|V| + |E|)\)。
- 总复杂度:\(O(|E| \log |E|) + O(|E| \cdot (|V| + |E|)) = O(|E|^2)\)。
这个复杂度在稠密图(\(|E| \approx |V|^2\))上表现为 \(O(|V|^4)\),效率较低。这也是 Reverse-Delete 算法虽然思想优雅,但不如 Kruskal(\(O(|E| \log |V|)\))和 Prim(\(O(|E| + |V| \log |V|)\))算法常用的主要原因。
步骤5:优化思路与示例
一个重要的优化是提前终止:当剩余边数等于 \(|V| - 1\) 时,已经形成了一棵树,算法可以立即停止,因为树一定是连通的且边数最少。
示例:
考虑一个简单的四边形(四个顶点,四条边),顶点为 {A, B, C, D},边和权重为:AB=1, BC=2, CD=3, DA=4, AC=5, BD=6(假设是带对角线的完全图 K4 的子集,但为了简单,我们只取这些边,并确保图连通)。
- 初始 T 包含所有6条边。按权重从大到小排序:BD(6), AC(5), DA(4), CD(3), BC(2), AB(1)。
- 检查 BD(6):删除后图仍连通(例如可通过 A-C-D-A 等路径连接B和D),删除。
- 检查 AC(5):删除后图仍连通,删除。
- 检查 DA(4):删除后图仍连通(路径 A-B-C-D 连接了A和D),删除。
- 此时 T 剩下 {CD(3), BC(2), AB(1)},边数=3,顶点数=4。检查 CD(3):删除后,顶点 D 将无法连接到其他顶点(不连通),所以必须保留 CD。
- T 仍为 {CD, BC, AB},已满足 |V|-1=3 条边,算法终止。总权重为 3+2+1=6,这是一个最小生成树。
总结
Reverse-Delete 算法从一个“富足”的状态(整个图)开始,通过不断剔除不必要的大权重边,最终得到最小生成树。其核心是环性质,并通过在每次删除时进行连通性检查来确保最终结构的连通性。虽然其理论复杂度较高,但它完美诠释了 MST 问题中贪心策略的另一种对称视角,并且当图以边列表形式给出且删除操作高效时,在特定场景下有一定应用价值。