解决最小生成树问题常见的算法有 Kruskral算法和Prim算法。
Kruskal算法
Kruskal算法是基于边的贪心算法。首先将所有边按照权值排序,然后逐步将权值最小的边加入生成树中,确保不形成环。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Edge {
int u, v, weight;
bool operator<(const Edge& other) const {
return weight < other.weight;
}
};
class DisjointSet {
public:
DisjointSet(int n) : parent(n), rank(n, 0) {
for (int i = 0; i < n; ++i) {
parent[i] = i;
}
}
int find(int u) {
if (parent[u] != u) {
parent[u] = find(parent[u]);
}
return parent[u];
}
void unite(int u, int v) {
int rootU = find(u);
int rootV = find(v);
if (rootU != rootV) {
if (rank[rootU] > rank[rootV]) {
parent[rootV] = rootU;
} else if (rank[rootU] < rank[rootV]) {
parent[rootU] = rootV;
} else {
parent[rootV] = rootU;
++rank[rootU];
}
}
}
private:
vector<int> parent;
vector<int> rank;
};
int kruskal(int n, vector<Edge>& edges) {
sort(edges.begin(), edges.end());
DisjointSet ds(n);
int mstWeight = 0;
for (const auto& edge : edges) {
int u = edge.u;
int v = edge.v;
int weight = edge.weight;
if (ds.find(u) != ds.find(v)) {
ds.unite(u, v);
mstWeight += weight;
// Optional: Store the edge in the MST if needed
}
}
return mstWeight;
}
int main() {
int n = 4; // Number of vertices
vector<Edge> edges = {
{0, 1, 10},
{0, 2, 6},
{0, 3, 5},
{1, 3, 15},
{2, 3, 4}
};
cout << "Weight of MST is " << kruskal(n, edges) << endl;
return 0;
}
Prim算法
Prim算法是基于顶点的贪心算法。初始化一个包含一个顶点的生成树,然后逐步将与生成树相连且权值最小的边加入生成树中。
#include <iostream>
#include <vector>
#include <climits>
using namespace std;
const int INF = INT_MAX;
int prim(int n, const vector<vector<int>>& graph) {
vector<int> key(n, INF);
vector<bool> inMST(n, false);
key[0] = 0;
int mstWeight = 0;
for (int count = 0; count < n - 1; ++count) {
int minKey = INF;
int u;
for (int v = 0; v < n; ++v) {
if (!inMST[v] && key[v] < minKey) {
minKey = key[v];
u = v;
}
}
inMST[u] = true;
mstWeight += minKey;
for (int v = 0; v < n; ++v) {
if (graph[u][v] && !inMST[v] && graph[u][v] < key[v]) {
key[v] = graph[u][v];
}
}
}
return mstWeight;
}
int main() {
int n = 4; // Number of vertices
vector<vector<int>> graph = {
{0, 10, 6, 5},
{10, 0, 0, 15},
{6, 0, 0, 4},
{5, 15, 4, 0}
};
cout << "Weight of MST is " << prim(n, graph) << endl;
return 0;
}