最小生成树之普里姆(prime)算法
参考:
(48条消息) 最小生成树详解(模板 + 例题)_潘小蓝的博客-CSDN博客_最小生成树例题详解
思路:
把点和边的值都赋为无穷大
1.有n个点,寻找n次
2.寻找最小的点,要求:未连通viss[j]=0,最小
3.如果找到最小点的dist不为无穷大
4.存储dist,标记当前点(vis[cur]=1)
5.改变与当前最小点连通的点k的dist的值(k也未被连通过)
6.寻找n次后返回sum
7.若sum不为无穷大,则输出
#include<bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; const int maxn=1000; int dist[maxn];//点的最小值 int vis[maxn];//标记是否已经求完了 int a[maxn][maxn];//路径的权值,有两个部分:u到v,v到u都为w int m,n,u,v,w; long long sum=0; int prime(int pos) { dist[pos]=0;//pos=1(第一个节点)与自己的距离为0 for(int i=1;i<=n;i++)//n个节点,判断n次 { int cur=-1; for(int j=1;j<=n;j++)//寻找最小结点,绝对与当前的那个点连通 // 因为:一开始每个点都是无穷大,改变dist数组的元素只与下面的k循环有关 { if(!vis[j]&&(cur==-1||dist[j]<dist[cur])) cur=j; } //是否为无穷大 if(dist[cur]>=INF) return INF; sum+=dist[cur]; //把当前的点标记为1 vis[cur]=1; for(int k=1;k<=n;k++)//更新与当前点相邻的点k的dist { if(!vis[k])//未被归入树中 { dist[k]=min(dist[k],a[cur][k]);//必须与cur连通,不然a[cur][k]的值为无穷大 } } } return sum; } int main() { cin>>n>>m; //一开始把路径和点的值都赋为无穷大 memset(a,0x3f,sizeof(a)); memset(dist,0x3f,sizeof(dist)); for(int i=1;i<=m;i++) { cin>>u>>v>>w; //给路径赋值,两个方面a[u][v],a[v][u],全部为w a[u][v]=min(a[u][v],w); a[v][u]=min(a[u][v],w); } long long value=prime(1); //返回的值是否为无穷大 if(value>=INF) { puts("impossible"); } else { printf("%lld",sum); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律