kruskal是个贪心算法,对于n个节点的图,最小生成树有n-1条边。
初始设所有点为孤立点,我们每次取权值最小的边,如果该边两端点尚未连通,那么该边就是最小生成树的一条边,接着连通两点。
节点是否连通用到了并查集。
root = [i for i in range(n+1)]
def find_root(i, root):
if root[i] != i:
root[i] = find_root(root[i], root)
return root[i]
使用root数组记录节点i的祖先节点,如果两个节点拥有共同的祖先,则说明两节点连通。
# 构造图,使用edges存储所有的边
n, m = list(map(int, input().split()))
edges, mst = [], []
for _ in range(m):
x, y, z = list(map(int, input().split()))
edges.append((x, y, z)) # 节点1、节点2、权值
# 将所有边按权值排序
edges.sort(key = lambda item: item[2])
# 构造最小生成树(mst)
for e in edges:
if len(mst) == n-1:
break
x, y, z = e
rx = find_root(x, root)
ry = find_root(y, root)
if rx == ry: # 如果两个节点连通
continue
mst.append(e)
root[rx] = root[ry] # 连通两个节点
你可以在洛谷 P3366练习kruskal算法。