AcWing 858. Prim算法求最小生成树
原题链接
简单
作者:
sailor
,
2021-03-13 09:12:25
,
所有人可见
,
阅读 306
C++ 代码
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=510,INF=0x3f3f3f3f;
int n,m;
int g[N][N];
int dist[N];//存放i顶点到集合的最短距离
bool st[N];//判断i顶点是否在集合中了
int prim()
{
memset(dist,0x3f,sizeof dist);
int res=0;//存放最小生成树的长度
for(int i=0;i<n;i++)//n次遍历,每次加一个顶点到集合中
{
int t=-1;
for(int j=1;j<=n;j++)//找到距离当前集合最近的点
if(!st[j]&&(t==-1||dist[t]>dist[j]))
t=j;//如果j不在集合中,并且j是第一个顶点或者j到集合的距离更小
//INF只是一个标志而已,注意!for循环执行第一次的时候,res是不加的
if(i&&dist[t]==INF) return INF;//如果图不连通
if(i) res+=dist[t];//找到第二个顶点的时候就可以在结果上加上这个边长了
//以刚加入集合的点t,更新其他点到集合的最短距离。但是有点点有可能存在负的自环,dist[t]有可能一直变小,
//但是已经无所谓了,反正dist[t]在上一步已经被加进去了
for(int j=1;j<=n;j++) dist[j]=min(dist[j],g[t][j]);
//for循环执行第一次的时候,t等于1,从1顶点开始向外扩散
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;
}