Prim算法
算法流程:
(1)初始化所有点到已加入点集合的距离为INF。
(2)做n次遍历,每次从未加入集合的点中找到离集合距离最小的点,将该点加入到生成树中。
(3)在每次循环中一旦找到距离最小的点后,使用该点来更新集合外的点到集合的距离。
使用的数据结构:领接矩阵(稠密图)
代码如下:
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 510, INF = 0x3f3f3f3f; int g[N][N]; int dist[N]; // 表示每个点到集合的距离 bool st[N]; int n, m; int prim() { // 初始化所有距离为INF memset(dist, 0x3f, sizeof dist); // 迭代N次,找到N个点 int res = 0; for(int i=0;i<n;i++) { int t = -1; for(int j=1;j<=n;j++) { // 从集合外找到离集合最近的一个点 if(!st[j] && (t == -1 || dist[t] > dist[j])) t = j; } // 如果不是第一个点,且离集合的距离为INF,则表示该图为非联通图 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); while(m--) { int u, v, w; cin >> u >> v >> w; g[u][v] = g[v][u] = min(g[u][v], w); } int res = prim(); if(res > INF / 2) puts("impossible"); else cout << res << endl; return 0; }

浙公网安备 33010602011771号