prim算法求最小生成树
#include<bits/stdc++.h>
using namespace std;
const int N=600;
int g[N][N];//n的平方约等于m,所以用邻接矩阵,存放权值。g[i][j]表示边ij的长度为g[i][j]
const int inf=0x3f3f3f3f;//无穷大0x3f3f3f3f
int dist[N];//该点到集合里点的最小值
bool st[N];//是否在已经选中的集合里,true表示在集合里
int m,n;//n个顶点,m条边
int prim(){
memset(dist,0x3f,sizeof dist);
int res=0;
for(int i=0;i<n;i++){//n轮循环把n个点按prim算法依次放入集合里
int t=-1;
for(int j=1;j<=n;j++){
if(!st[j]&&(t==-1||dist[t]>dist[j])){//t为当前到集合的最小值。条件是这个点没访问过并且(这个当前j这个点如果是第一个点(t=-1)或者是能缩短当前已经找到最近点距离)
t=j;
}
}
if(i&&dist[t]==inf){//i不是第一个点,因为第一个点一定要放进。这个表达式是说连通不了返回无穷大。
return inf;
}
//先加再更新dist,因为防止自环,自环是不能在生成树里因为假设有个自环g[t][t]=-6要是先更新dist会更新dist[t]生成树里会加上g[t][t]=-6这条环!
if(i){//不是第一个点且连通-->更新最小生成树权重和
res=res+dist[t];
}
st[t]=true;//t这个点放入集合
for(int j=1;j<=n;j++ ){//用t这个点更新集合外各各点到集合内点的距离,因为t放入集合就要考虑t这个点与集合外各点距离能否更新最小值到集合内距离
dist[j]=min(dist[j],g[t][j]);
}
}
return res;
}
int main(){
cin>>n>>m;
memset(g,0x3f,sizeof g);
int u,v,w;
while(m--){
cin>>u>>v>>w;
g[u][v]=g[v][u]=min(w,g[u][v]);//无向图,两个方向权值一样,为了防止有重边所以要取最小
}
int t=prim();
if(t==inf){
cout<<"impossible";
}
else{
cout<<t;
}
return 0;
}
标签:dist,int,最小,生成,算法,集合,prim,inf From: https://www.cnblogs.com/luckyhappyyaoyao/p/18335896