原题链接:
题解:
参考详解:
AcWing 858. Prim算法求最小生成树:图解+详细代码注释(带上了保存路径) - AcWing
对于稠密图而言(m=n^2)的情况,使用朴素版Prim算法更好;
而对于稀疏图而言(m=n)的情况,则使用Kruskal算法更好,相比之下,堆优化版本的Prim反而没了用武之地。
Dijkstra是更新到起始点的距离,而Prim是更新到集合S的距离
套板子即可
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 5e2 + 10;
const int INF = 0x3f3f3f3f;
int n, m;
int dis[N], g[N][N], s[N];
int prim() {
memset(dis, 0x3f, sizeof(dis));
int res = 0;
for (int i = 0;i < n;i++) {//寻找离集合s距离最近的点
int t = -1;
for (int j = 1;j <= n;j++) {
if (!s[j] && (t == -1 || dis[t] > dis[j]))
t = j;
}
if (i && dis[t] == INF) return INF;//表示非联通图
if (i) res += dis[t];//当集合s中结点个数不为1时
s[t] = 1;
for (int j = 1;j <= n;j++) dis[j] = min(dis[j], g[t][j]);//更新其余各点到s的距离
}
return res;
}
int main() {
cin >> n >> m;
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= n;j++) {
if (i == j) g[i][j] = 0;
else g[i][j] = INF;
}
}
for (int i = 0;i < m;i++) {
int x, y, z;cin >> x >> y >> z;
g[x][y] = g[y][x] = min(g[x][y], z);
}
int t = prim();
if (t == INF) cout << "impossible";
else cout << t;
}