普里姆算法中的Min,使用c++实现
时间: 2024-05-10 08:16:25 浏览: 74
普里姆算法是求解最小生成树的算法,其中Min指的是选取当前集合中距离最近的点,下面是使用C++实现的代码:
```c++
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
const int MAXN = 1005;
const int INF = 0x3f3f3f3f;
int n, m; // 点数和边数
int g[MAXN][MAXN]; // 图的邻接矩阵
bool vis[MAXN]; // 标记是否已加入生成树
struct Edge {
int from, to, weight;
Edge(int u, int v, int w) : from(u), to(v), weight(w) {}
};
struct cmp { // 小根堆比较函数
bool operator() (Edge& a, Edge& b) {
return a.weight > b.weight;
}
};
vector<Edge> MST; // 最小生成树边集
void Prim() {
memset(vis, false, sizeof(vis)); // 初始化标记数组
priority_queue<Edge, vector<Edge>, cmp> pq; // 小根堆
for (int i = 1; i <= n; i++) {
if (g[1][i] != INF) { // 从1号点开始
pq.push(Edge(1, i, g[1][i]));
}
}
vis[1] = true; // 标记1号点已加入生成树
while (!pq.empty()) {
Edge e = pq.top();
pq.pop();
if (vis[e.to]) {
continue;
}
vis[e.to] = true;
MST.push_back(e);
for (int i = 1; i <= n; i++) {
if (!vis[i] && g[e.to][i] != INF) {
pq.push(Edge(e.to, i, g[e.to][i]));
}
}
}
}
int main() {
cin >> n >> m;
memset(g, INF, sizeof(g)); // 初始化邻接矩阵
for (int i = 1; i <= n; i++) {
g[i][i] = 0; // 自己到自己的距离为0
}
for (int i = 1; i <= m; i++) {
int u, v, w;
cin >> u >> v >> w;
g[u][v] = g[v][u] = w; // 无向图
}
Prim();
int sum = 0;
for (int i = 0; i < MST.size(); i++) {
sum += MST[i].weight;
}
cout << sum << endl; // 输出最小生成树的权值和
return 0;
}
```
其中,邻接矩阵g的初始化为INF,表示两点之间没有边相连,自己到自己的距离为0。将1号点加入生成树之后,将与1号点相邻的点加入小根堆pq。每次取出堆顶元素e,如果e.to已经加入生成树,则跳过;否则将e.to加入生成树,将e加入最小生成树边集,再将与e.to相邻的未加入生成树的点加入小根堆pq。最终,输出最小生成树的权值和。
阅读全文