prim算法求最小生成树

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;
}

 

posted @ 2024-08-01 16:39  Annaprincess  阅读(21)  评论(0)    收藏  举报