PrepStack · Markdown HTML

Kruskal 最小生成树

并查集、MST 与离线激活 · HTML

数学 / 逻辑形态

图 G=(V,E),边权可比较;求含 |V|-1 条边的生成树 T,使边权总和最小。

识别信号

容易误判的相似信号

SignalWhy it is different
单源最短路MST 最小化整棵树总边权,不保证源到各点路径最短。
有向最小连接普通 Kruskal 面向无向图;有向生成结构使用不同算法。

核心不变量

扫描到当前权重时,已选森林可扩展成某棵 MST;只接受跨越不同组件的最轻边。

状态、转移与处理顺序

ItemDefinition
State排序边列表、表示森林的 DSU、累计权重 total、已选边 chosen。
Transition按权重非降序取边;union 成功则选择并累加,失败表示会成环。
Frontier / order尚未扫描边按权重有序;当前最轻跨组件边是 cut property 保证的安全边。

Python 骨架

def kruskal(n, edges):
    p, sz = list(range(n)), [1] * n
    def find(x):
        while x != p[x]:
            p[x] = p[p[x]]; x = p[x]
        return x
    def union(a, b):
        a, b = find(a), find(b)
        if a == b: return False
        if sz[a] < sz[b]: a, b = b, a
        p[b] = a; sz[a] += sz[b]
        return True
    total, chosen = 0, []
    for w, u, v in sorted(edges):
        if union(u, v):
            total += w; chosen.append((u, v, w))
            if len(chosen) == n - 1: break
    return (total, chosen) if len(chosen) == n - 1 else None

正确性思路

  1. cut property 保证跨任一当前割的最轻边属于某棵 MST。
  2. 排序保证接受边不重于尚未处理的替代边。
  3. DSU 拒绝组件内部边,所以森林始终无环。
  4. 连通时选满 n-1 条安全边,形成最小生成树。

复杂度

TimeSpaceParameters
O(E log E),排序主导O(V+E)V 为顶点数,E 为边数;DSU 部分 O(E α(V))

边界条件

错误模式

PatternWhy it fails / fix
排序字段放错若边存成 (u,v,w),必须显式按 w 排序。
未在 V-1 条边停止树已完成后继续扫描没有价值。
漏查连通性少于 V-1 条边时累计值只是森林,不是完整答案。

选择与排除规则

相关模板

RelationTemplateBoundary
瓶颈关联Minimax / Bottleneck Dijkstra只最小化两点路径最大边
共享排序骨架离线排序 + 逐步激活 + 并查集边权充当激活阈值

原创微型例子

环节内容
Result依次选 1、2、3,总成本 6。
Scenario四站点候选边权为 2、1、3、8、5。
Walkthrough前三条安全边已连通四点;昂贵边无需再看。

Recall prompts

我的补充