克鲁斯卡尔算法
克鲁斯卡尔算法(Kruskal Algorithm)是一种用于求解最小生成树(Minimum Spanning Tree, MST)的经典贪心算法,适用于无向加权图。
核心思想:每次选择当前权重最小、且不会形成环的边加入生成树。
关键点:使用并查集判断是否会形成环。
时间复杂度
- 排序边:O(E log E)
- 并查集操作:近似 O(E α(N))(α 是反阿克曼函数,极小)
总体复杂度:O(E log E)
流程图:
代码:
def kruskal(n: list[int], edges: list[list[int]]): # [[端点1, 端点2, 权重], ...]
edges.sort(key=lambda x: x[2]) # 按权重排序
dsu = DSU(n)
mst = []
for u, v, w in edges:
if dsu.find(u) == dsu.find(v):
continue
dsu.union(u, v)
mst.append((u, v, w))
return mst
练习题:3600.升级后最大生成树稳定性
并查集
并查集(Union Find / Disjoint Set Union) 是一种用于管理分组的数据结构(一般使用树形结构来表示)~
(1)Find:查询 a 元素和 b 元素是否为同一组(只需要判断他们的 root 根节点是否为同一个即可)
(2)Union:合并元素 a 和 b 为同一组
代码
class DSU:
def __init__(self, parent: list[int]):
this.parent = parent
def find(self, x: int):
if self.parent[x] != x:
self.parent[x] = self.find(self.parent[x])
return self.parent[x]
def union(self, x: int, y: int):
px = self.find(x)
py = self.find(y)
self.parent[px] = py