最小生成树唯一性判定问题
问题描述
给定一个连通的无向图 \(G = (V, E)\),其中每条边 \(e \in E\) 有一个权重 \(w(e)\)。我们已经知道如何求其最小生成树(Minimum Spanning Tree,MST)。现在的问题是:如何判断这个图的最小生成树是否唯一? 也就是说,是否存在另一棵生成树 \(T' \neq T\),其总权重等于最小生成树 \(T\) 的总权重?
理解核心
最小生成树不唯一的原因在于,图中可能存在权重相等的边,或者存在非树边可以替换树中的某条边,而不增加总权重。因此,判定唯一性的关键在于检查是否存在这样的“等价替换”。
常见算法思路
这里介绍一个基于 Kruskal 算法的判定方法,其核心思想是:
- 首先使用 Kruskal 算法找到一棵最小生成树 \(T\),并记录其总权重 \(W\)。
- 然后检查每一条未被选入 \(T\) 的边 \(e = (u, v)\),看它是否能与 \(T\) 中的某些边构成一个“可替换环”,从而生成另一棵总权重相同的生成树。
详细步骤
第一步:运行 Kruskal 算法找到 MST
Kruskal 算法的步骤简述:
- 将所有边按权重从小到大排序。
- 初始化一个空的边集 \(T\) 作为 MST,并初始化一个并查集,每个顶点自成一个集合。
- 按顺序考虑每条边 \(e = (u, v)\):
- 如果 \(u\) 和 \(v\) 不在同一个集合(即加入 \(e\) 不会形成环),则将 \(e\) 加入 \(T\),并在并查集中合并 \(u\) 和 \(v\) 所在的集合。
- 否则(即 \(u\) 和 \(v\) 已在同一集合),跳过该边(此边成为非树边)。
- 当 \(T\) 包含 \(|V|-1\) 条边时停止,得到一棵 MST。
关键记录:
- 在运行过程中,标记每条边是否被选入 \(T\)。
- 记录最终 MST 的总权重 \(W\)。
第二步:检查每条未被选入的边
对于每一条未被选入 \(T\) 的边 \(e = (u, v)\)(称为候选非树边),我们需要检查:是否存在一棵 MST 包含 \(e\),且总权重仍为 \(W\)?
具体检查方法:
- 找出在 MST \(T\) 中连接 \(u\) 和 \(v\) 的唯一路径 \(P\)(因为 \(T\) 是树,任意两点间只有一条路径)。
- 检查路径 \(P\) 上是否有边的权重等于 \(e\) 的权重。
- 如果存在这样的边 \(e'\)(即 \(w(e') = w(e)\)),那么我们可以用 \(e\) 替换 \(e'\),得到另一棵生成树 \(T' = T \setminus \{e'\} \cup \{e\}\)。
- 由于替换后总权重不变(\(w(e') = w(e)\)),且 \(T'\) 仍是生成树(替换后依然连通且无环),因此存在另一棵权重相同的 MST,即 MST 不唯一。
- 此时可以直接返回“不唯一”。
- 如果对于所有未被选入的边 \(e\),其对应的路径 \(P\) 中,所有边的权重都严格小于 \(w(e)\)(因为 Kruskal 按权重递增选边,树边权重不会大于非树边),则无法进行等权重替换,MST 是唯一的。
为什么只需检查权重相等的边?
因为在 MST \(T\) 中,路径 \(P\) 上的边权重都不大于 \(w(e)\)(Kruskal 性质)。如果 \(P\) 上某边权重小于 \(w(e)\),替换后总权重会增加,不会得到另一棵 MST。只有当权重相等时,替换才可能保持总权重不变。
第三步:路径权重的快速检查
直接对每条非树边求路径并检查最大权重,最坏情况需 \(O(|E| \cdot |V|)\)。我们可以优化:
- 在找到 MST \(T\) 后,将其视为一棵树。
- 预处理这棵树,以便快速查询树上任意两点间路径的最大边权重。
- 常用方法:树上倍增(Binary Lifting)或树链剖分。
- 树上倍增:预处理每个节点向上 \(2^k\) 步的祖先及路径上的最大边权重。
- 查询 \(u\) 和 \(v\) 之间路径的最大边权重时,可以在 \(O(\log |V|)\) 时间内完成。
优化后的算法流程:
- 运行 Kruskal,得到 MST \(T\) 并标记树边。
- 以任意节点为根,将 \(T\) 转化为有根树。
- 进行树上倍增预处理(计算祖先和路径最大权重)。
- 对于每条非树边 \(e = (u, v)\):
- 使用倍增法查询 \(T\) 中 \(u\) 到 \(v\) 路径上的最大边权重 \(max\_weight\)。
- 如果 \(max\_weight = w(e)\),则发现可替换边,返回“不唯一”。
- 若检查完所有非树边均未发现相等,则返回“唯一”。
时间复杂度
- Kruskal 算法:\(O(|E| \log |E|)\)(排序边)。
- 树上倍增预处理:\(O(|V| \log |V|)\)。
- 检查每条非树边:共 \(O(|E| - |V| + 1)\) 条,每条查询 \(O(\log |V|)\),总 \(O(|E| \log |V|)\)。
- 总复杂度:\(O(|E| \log |E|)\),与 Kruskal 同量级,实际高效。
举例说明
考虑一个简单图:
顶点:\(V = \{A, B, C\}\)
边:\((A, B, 1), (B, C, 2), (A, C, 2)\)(括号内为两端点和权重)
- 运行 Kruskal:先选 \((A, B, 1)\),然后可以在 \((B, C, 2)\) 和 \((A, C, 2)\) 中任选一条(权重相同),得到一棵 MST,例如 \(T = \{(A, B, 1), (B, C, 2)\}\),总权重 3。
- 检查非树边 \((A, C, 2)\):
- 在 \(T\) 中,连接 \(A\) 和 \(C\) 的路径是 \(A \to B \to C\)。
- 路径上的边权重为 1 和 2,最大权重为 2,等于 \(w(A, C) = 2\)。
- 因此,可用 \((A, C, 2)\) 替换 \((B, C, 2)\),得到另一棵 MST \(\{(A, B, 1), (A, C, 2)\}\),权重同为 3。
- 结论:MST 不唯一。
总结
判定最小生成树唯一性的核心在于检查是否存在非树边可以等权重替换树边。基于 Kruskal 和树上倍增的算法能高效解决这一问题。若发现任何这样的可替换边,则 MST 不唯一;否则,唯一。