prim算法求最小生成树代码
时间: 2023-07-22 08:08:59 浏览: 94
以下是使用 Prim 算法求解最小生成树的代码(C++实现):
```cpp
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
// 存储图的邻接表
vector<pair<int, int>> adj[100001];
// Prim 算法求最小生成树,返回最小生成树的总权值
int prim(int n, int start) {
int res = 0; // 最小生成树的总权值
vector<bool> visited(n + 1, false); // 记录每个节点是否已经被加入集合
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; // 小根堆,存储从集合中出发的边
// 将起点加入集合
visited[start] = true;
for (auto p : adj[start]) {
pq.push({ p.second, p.first });
}
while (!pq.empty()) {
auto [w, u] = pq.top();
pq.pop();
if (visited[u]) continue; // 如果这个点已经在集合中,跳过
visited[u] = true;
res += w; // 将这条边的权值加入最小生成树的总权值中
for (auto p : adj[u]) {
if (!visited[p.first]) {
pq.push({ p.second, p.first });
}
}
}
return res;
}
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({ v, w });
adj[v].push_back({ u, w });
}
int start;
cin >> start; // 输入起点
cout << prim(n, start) << endl; // 输出最小生成树的总权值
return 0;
}
```
其中,`adj` 数组存储了图的邻接表,`pq` 存储了从集合中出发的边,`visited` 数组记录每个节点是否已经被加入集合。在 `prim` 函数中,我们首先将起点加入集合,然后将起点可以到达的所有节点加入小根堆,依次取出堆顶元素,如果这个节点已经在集合中,则跳过;否则,将它加入集合,并将它可以到达的所有节点加入小根堆中。最后返回最小生成树的总权值即可。
阅读全文