最小生成树(Minimum Spanning Tree, MST)是图论中的一个重要概念,常用于解决网络设计、聚类分析等问题。最小生成树算法用于在带权无向图中找到一棵包含所有顶点的树,且树中所有边的权重之和最小。常见的最小生成树算法包括 Kruskal算法 和 Prim算法。
1. Kruskal算法
Kruskal算法是一种基于贪心策略的算法,通过逐步选择权重最小的边来构建最小生成树。
算法步骤:
-
初始化:将图中的所有边按权重从小到大排序。
-
选择边:从权重最小的边开始,依次选择边。如果该边的两个顶点不在同一个集合中(即不形成环),则将该边加入生成树中,并将两个顶点合并到同一个集合中。
-
终止条件:重复上述过程,直到生成树中包含 V−1V−1 条边(VV 是顶点数)。
实现细节:
-
使用 并查集(Disjoint Set Union, DSU) 数据结构来管理顶点的集合,判断是否形成环。
-
时间复杂度:O(ElogE)O(ElogE),其中 EE 是边的数量。
伪代码:
def kruskal(graph):
# 初始化并查集
parent = [i for i in range(V)]
result = [] # 存储最小生成树的边
edges = sorted(graph.edges, key=lambda x: x.weight) # 按权重排序
for edge in edges:
u_root = find(parent, edge.u)
v_root = find(parent, edge.v)
if u_root != v_root: # 不形成环
result.append(edge)
union(parent, u_root, v_root)
return result
例题:挖沟
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
#include<vector>
#include<math.h>