C++语言实现最小生成树算法(Minimum Spanning Tree)
在C++中实现最小生成树(Minimum Spanning Tree, MST)算法,同样可以使用Kruskal算法或Prim算法。以下是使用Kruskal算法实现MST的示例代码。
Kruskal算法
Kruskal算法的主要思想是将所有边按照权重从小到大排序,然后逐一添加到生成树中,如果添加一条边会形成环,则跳过这条边,直到生成树中包含所有顶点。
示例代码:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 边结构体
struct Edge {
int from, to, weight;
};
// 并查集类
class UnionFind {
public:
UnionFind(int n) {
parent.resize(n);
rank.resize(n);
for (int i = 0; i < n; ++i) {
parent[i] = i;
rank[i] = 0;
}
}
int Find(int x) {
if (parent[x] != x) {
parent[x] = Find(parent[x]);
}
return parent[x];
}
void Union(int x, int y) {
int rootX = Find(x);
int rootY = Find(y);
if (rootX != rootY) {
if (rank[rootX] > rank[rootY]) {
parent[rootY] = rootX;
} else if (rank[rootX] < rank[rootY]) {
parent[rootX] = rootY;
} else {
parent[rootY] = rootX;
rank[rootX]++;
}
}
}
private:
vector<int> parent;
vector<int> rank;
};
// Kruskal算法
vector<Edge> Kruskal(vector<Edge>& edges, int n) {
sort(edges.begin(), edges.end(), [](Edge a, Edge b) {
return a.weight < b.weight;
});
UnionFind uf(n);
vector<Edge> mst;
for (auto& edge : edges) {
if (uf.Find(edge.from) != uf.Find(edge.to)) {
uf.Union(edge.from, edge.to);
mst.push_back(edge);
}
}
return mst;
}
int main() {
vector<Edge> edges = {
{0, 1, 10},
{0, 2, 6},
{0, 3, 5},
{1, 3, 15},
{2, 3, 4}
};
int n = 4; // 节点数
vector<Edge> mst = Kruskal(edges, n);
cout << "Minimum Spanning Tree:" << endl;
for (auto& edge : mst) {
cout << "from " << edge.from << " to " << edge.to << ", weight: " << edge.weight << endl;
}
return 0;
}
代码解释:
- Edge结构体:表示图中的一条边,包含起点、终点和权重。
- UnionFind类:实现并查集数据结构,用于检测环。
- UnionFind构造函数:初始化并查集。
- Find方法:查找并查集中的代表元。
- Union方法:合并两个集合。
- Kruskal函数:实现Kruskal算法,首先对边按权重排序,然后逐一添加边到生成树中。
- main函数:示例数据,调用Kruskal函数并输出结果。
这个示例代码展示了如何在C++语言中实现Kruskal算法来求解最小生成树。你可以根据需要调整输入的边和节点数。