prim算法最小生成树 发表于 2017-12-20 | 分类于 C++ 这是在提交平台上的练习题的代码1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980#include <bits/stdc++.h>#define INF 0x3f3f3f3f#define N 1100using namespace std;int mp[N][N]; //邻接矩阵存储图int dis[N]; //标记数组int vis[N]; //用来记录当前生成树到每个节点的距离int sum, n, m;//n代表节点数 sum保存生成树的权值总和void prim(){ sum=0; //最小生成树的权值总和初始化为0 int mm; memset(vis, false, sizeof(vis)); //初始化节点均没有被访问 for(int i = 1; i <= n; i++) { dis[i] = mp[1][i]; //我们从0号节点开始生成树 } vis[1] = true; //生成树的根(起点)标记访问 int pos; //用来记录每一次循环找到的节点的编号 int d = 0; //标记变量 for(int i = 1; i < n; i++) //要生成n-1条边,所以循环n-1次 { mm = INF; for(int j = 1; j <= n; j++) //对dis数组进行遍历,找到值最小的 { if(!vis[j] && dis[j] < mm) { mm = dis[j]; pos = j; } } if(mm == INF) //如果在此跳出循环,表示有城市之间不能连通 { d = 1; break; } sum += mm; //加上找到的最小权值 vis[pos] = true; //标记找到的该节点被访问 for(int j = 1; j <= n; j++) //更新dis数组 { if(!vis[j] && dis[j] > mp[pos][j]) { dis[j] = mp[pos][j]; //如果该点还没有被访问过, //更新生成树到该点的距离; } } } if(d == 0) printf("%d\n", sum); //n-1次循环完毕后输出权值总和 else printf("-1\n");}int main(){ while(cin >> n >> m) { for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) //对mp数组初始化 { if(i == j) mp[i][j] = 0; else mp[i][j] = INF; } } while(m--) { int a, b, c; scanf("%d%d%d", &a, &b, &c); if(mp[a][b] > c) //如果存在重边,取最小值 mp[a][b] = mp[b][a] = c; } prim(); //执行普利姆算法 } return 0;}