利用Prim算法或者克鲁斯卡尔算法,求解无向图的最小生成树,输出最小生成树。在主函数main( )中进行测试验证
时间: 2023-07-22 17:10:09 浏览: 84
好的,我已经理解了你的问题。以下是使用Prim算法求解无向图的最小生成树的代码示例,你可以在自己的IDE或者在线编译器中运行测试:
```c++
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int MAXN = 1005;
const int INF = 0x3f3f3f3f;
int n, m; // n 表示图中的点数,m 表示边数
int g[MAXN][MAXN]; // 图的邻接矩阵表示
bool vis[MAXN]; // 标记每个点是否已经加入最小生成树
int dis[MAXN]; // 存储每个点到最小生成树的距离
int pre[MAXN]; // 存储每个点在最小生成树中的父节点
struct Edge {
int u, v, w;
Edge(int _u, int _v, int _w): u(_u), v(_v), w(_w) {}
};
vector<Edge> edges; // 存储所有边的信息
void prim(int u0) {
// 初始化
memset(vis, false, sizeof(vis));
memset(dis, INF, sizeof(dis));
memset(pre, -1, sizeof(pre));
dis[u0] = 0;
// 将起点加入最小生成树
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
pq.push(make_pair(dis[u0], u0));
while (!pq.empty()) {
// 取出当前距离最近的点
pair<int, int> p = pq.top();
pq.pop();
int u = p.second;
if (vis[u]) continue; // 已经加入最小生成树了
vis[u] = true;
for (int v = 1; v <= n; v++) {
if (!vis[v] && dis[v] > g[u][v]) { // 更新最小距离
dis[v] = g[u][v];
pre[v] = u;
pq.push(make_pair(dis[v], v));
}
}
}
}
void addEdge(int u, int v, int w) {
edges.push_back(Edge(u, v, w));
edges.push_back(Edge(v, u, w));
}
void printMST() {
int sum = 0;
for (int i = 0; i < edges.size(); i += 2) {
if (pre[edges[i].v] == edges[i].u) {
cout << edges[i].u << " - " << edges[i].v << " : " << edges[i].w << endl;
sum += edges[i].w;
} else {
cout << edges[i].v << " - " << edges[i].u << " : " << edges[i].w << endl;
sum += edges[i].w;
}
}
cout << "The total weight of MST is " << sum << endl;
}
int main() {
cin >> n >> m;
memset(g, INF, sizeof(g));
for (int i = 0; i < m; i++) {
int u, v, w;
cin >> u >> v >> w;
g[u][v] = g[v][u] = w;
addEdge(u, v, w);
}
prim(1);
printMST();
return 0;
}
```
以上代码中,使用邻接矩阵存储无向图,使用堆优化的Prim算法求解最小生成树,并输出最小生成树的边和权值。
你可以自己构造一些图,运行代码进行测试验证。
阅读全文