朴素prim算法模版
核心思想
1. 构造一个点集合,每次选择剩下的点中距离集合最近的点
2. 若当前点到集合距离为∞,则不存在最小生成树,否则将该点加入集合中
3. 并用该点到其他所有点的距离更新其他点到集合的最短距离
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 510, M = 100010, INF = 0x3f3f3f3f;
int g[N][N];
int dist[N]; //表示每个点到集合的最短距离
bool st[N]; // 表示点是否在构造的集合中,已经被选中
int n, m;
int prim() {
memset(dist, 0x3f, sizeof(dist)); // 初始化,每个点到集合的最短距离都是∞
int res = 0;
for (int i = 0; i < n; i++) { // 迭代n轮
int t = -1; //表示这轮还没有选点
for (int j = 1; j <= n; j++) {
if (!st[j] && (t == -1 || dist[j] < dist[t])) { // 没有选点,或者最小距离更小
t = j; // 这个距离最小的点就被更新
}
}
if (i && dist[t] == INF) return INF; //如果不是第一个点,且距离无穷大,则不存在
if (i) res += dist[t]; //否则就将该点先加入集合中
st[t] = true;
for (int j = 1; j <= n; j++) dist[j] = min(dist[j], g[t][j]); //然后用该点进行更新
}
return res;
}
int main() {
cin >> n >> m;
memset(g, 0x3f, sizeof(g));
for (int i = 0; i < m; i++) {
int a, b, v;
scanf("%d%d%d", &a, &b, &v);
g[a][b] = g[b][a] = min(g[a][b], v);
}
int t = prim();
if (t == INF) cout << "impossible" << endl;
else cout << t << endl;
return 0;
}