【最小生成树】畅通工程--Kruskal算法

//最小生成树,kruskal算法
//基础入门

#include<algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 105
struct Edge{//结构体表示边,其中包括两个点和权重
    int x,y,w;
    const bool operator<(const Edge& rhs)const{
    return w<rhs.w;//重载比较运算符,对w从小到大
    }
}edge[maxn];//数组相当边

int fa[maxn];//放顶点
int n,m;
int ans;
int find(int a){
    if(fa[a]==a){
        return a;
    }
    else{
        return fa[a]=find(fa[a]);
    }
}
int kruskal(){
    int ans=0;int cnt=0;
    for(int i=0;i<=m;i++){
    fa[i]=i;//初始化,每个顶点都是一个集合
    }
//对结构体进行排序·,从小到大,看上面比较运算符
    sort(edge, edge+n);
    
    //排序完成,进行边的遍历
    for(int i=0;i<n;i++){
        //边的两个点是否在同一集合
        int fx=find(edge[i].x);
        int fy=find(edge[i].y);
        //不是就相加 (连接)并查集
        //是,再相加(连接)就成回路,所以跳出
        if(fx!=fy){
        
            ans+=edge[i].w;
            fa[fx]=fy;
            cnt++;
            
        }
        if(cnt==m-1) break;//直到相加的边等于m-1条边(最小生成树,点全部连起来了)
    }
    if(cnt<m-1){
        ans=-1;
    }
    
    return ans;
}
int main(){
        
    while(scanf("%d%d",&n,&m),n){
    
        for(int i=0;i<n;i++){
            scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].w);
        }
        
        int ans=kruskal();
        if(ans == -1) printf("?\n");
        else{
        printf("%d\n",ans);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_39905871/article/details/81198049
今日推荐