用prim算法求给定无向连通网的最小生成树,输入无向连通网的顶点数,起始顶点及无向连通网各边的权值,输出第1行为顶点数,第2行为起始顶点,C++
时间: 2023-07-14 21:13:29 浏览: 112
最小生成树之普里姆prim算法C++实现
以下是使用Prim算法求解无向连通网最小生成树的C++代码:
```cpp
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 100;
const int INF = 0x3f3f3f3f;
int n, start;
int G[MAXN][MAXN];
int dist[MAXN]; // 存储当前已选节点到未选节点的最短距离
bool visited[MAXN]; // 标记节点是否已经被选中
struct Edge {
int v, w;
bool operator<(const Edge& e) const {
return w > e.w; // 小根堆,按照边权从小到大排序
}
};
vector<Edge> adj[MAXN]; // 存储每个节点的邻接边
void prim() {
// 初始化
for (int i = 0; i < n; i++) {
dist[i] = INF;
visited[i] = false;
}
dist[start] = 0;
// 将起始节点加入已选集合
priority_queue<Edge> pq;
pq.push({start, 0});
while (!pq.empty()) {
int u = pq.top().v;
pq.pop();
if (visited[u]) continue;
visited[u] = true;
// 更新当前已选节点到未选节点的最短距离
for (auto e : adj[u]) {
int v = e.v, w = e.w;
if (!visited[v] && w < dist[v]) {
dist[v] = w;
pq.push({v, w});
}
}
}
}
int main() {
cin >> n >> start;
start--;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> G[i][j];
if (G[i][j] > 0) {
adj[i].push_back({j, G[i][j]});
adj[j].push_back({i, G[i][j]});
}
}
}
prim();
// 输出结果
int sum = 0;
for (int i = 0; i < n; i++) {
if (dist[i] == INF) {
cout << "No solution." << endl;
return 0;
}
sum += dist[i];
}
cout << n << endl;
cout << start + 1 << endl;
for (int i = 0; i < n; i++) {
if (i != start) {
cout << start + 1 << " " << i + 1 << " " << dist[i] << endl;
}
}
cout << "The total weight is " << sum << endl;
return 0;
}
```
需要注意的是,Prim算法的时间复杂度为O(n^2),但是使用堆优化后可以优化到O(mlogn),其中m为边数。
阅读全文