Prim求最小生成树

题目传送门

Prim也挺简单的。我们来看一下具体思路

1.初始化dis距离数组为极大值。

2.迭代所有结点。

3.定义点t,用t来找到集合外距离最小的点,每次如果这个点不在集合里并且t还是初始值,或者distt>distj,就更新t的点。

4.特判,更新最小生成树的权值,然后用点t更新,其他点和集合的距离,将点t放入最小生成树。

是不是很像dij算法(迪杰斯特拉)?没错差距就只有一处,那就是一个是更新到起点的距离,一个是更新的到集合的距离,那什么是到集合的距离呢?

很简单,假设有一个点到集合有x条边,那其中最短的边就是到集合的距离。

时间复杂度O(n2),相较于Kruskal慢了很多,但毕竟他还能存哪些节点是最小生成树的,还可以吧。

#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int N = 510, INF = 0x3f3f3f3f; int n,m; int g[N][N],dis[N]; bool st[N];//表示点是否在集合当中 int prim() { memset(dis,0x3f,sizeof(dis)); 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 || dis[t] > dis[j])) t = j; } if(i && dis[t] == INF) return INF; if(i) res += dis[t];//如果不是第一个点,那么就把这个点用那条边和集合连起来 for (int j = 1; j <= n; j ++ ) dis[j] = min(dis[j],g[t][j]); st[t] = true; } return res; } int main() { scanf("%d%d", &n, &m); memset(g,0x3f,sizeof(g)); while (m -- ) { int a,b,c; scanf("%d%d%d", &a, &b, &c); g[a][b] = g[b][a] = min(g[a][b],c);//无向图 } int t = prim(); if(t == INF) puts("impossible"); else printf("%d\n",t); return 0; }

更好的视觉体验


__EOF__

本文作者ljfyyds
本文链接https://www.cnblogs.com/ljfyyds/p/16493747.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   ljfyyds  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示