用c++ 编写一个程序,实现求解带权连通图中最小生成树的算法。 具体要求:如果利用普里姆算法输出图中从顶点0出发的一棵最小生成树
时间: 2023-07-22 17:07:24 浏览: 111
最小生成树之普里姆prim算法C++实现
以下是用C++编写的普里姆算法求解带权连通图中最小生成树的程序:
```cpp
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 1005; // 最大顶点数
const int INF = 0x3f3f3f3f; // 无穷大
struct Edge {
int to, weight;
Edge(int t=0, int w=0): to(t), weight(w) {}
};
vector<Edge> adj[MAXN]; // 邻接表存图
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q; // 小根堆
int prim() {
int ans = 0;
bool vis[MAXN] = {false}; // 标记是否已加入最小生成树
vis[0] = true;
for (Edge e : adj[0]) {
q.push(make_pair(e.weight, e.to));
}
while (!q.empty()) {
int w = q.top().first, v = q.top().second;
q.pop();
if (vis[v]) continue;
vis[v] = true;
ans += w;
for (Edge e : adj[v]) {
if (!vis[e.to]) {
q.push(make_pair(e.weight, e.to));
}
}
}
return ans;
}
int main() {
int n, m;
cin >> n >> m; // 输入顶点数和边数
for (int i = 0; i < m; ++i) {
int u, v, w;
cin >> u >> v >> w; // 输入边的起点、终点和权值
adj[u].push_back(Edge(v, w));
adj[v].push_back(Edge(u, w));
}
int ans = prim(); // 求解最小生成树的权值和
cout << ans << endl;
return 0;
}
```
该程序的思路是:先用邻接表存储带权连通图,然后以顶点0为起点,将所有与顶点0相邻的边加入小根堆中,在每次循环中取出堆顶元素(即权值最小的边),如果该边的终点还没有被加入最小生成树,则将其加入最小生成树中,并将所有与该点相邻的边加入堆中。直到堆为空为止,此时得到的权值和即为最小生成树的权值和。
需要注意的是,由于输入的边是无向的,因此在邻接表中需要同时记录起点和终点,且在加边时需要将两个方向都加上。
阅读全文