最小生成树(Kruskal)

来源:互联网 发布:相马光子知乎 编辑:程序博客网 时间:2024/05/20 13:39
#include<iostream>#include<algorithm>using namespace std;int pre[100];struct edge{    int u,v,w;}edge[100];bool cmp(struct edge a,struct edge b){    return a.w<b.w;}int findf(int x){    int i=x;    while(pre[i]!=i){        i=pre[i];    }    int j=x,t;    while(pre[j]!=i){        t=pre[j];        pre[j]=i;        j=pre[j];    }    return i;}void join(int a,int b){    a=findf(a);    b=findf(b);    if(a!=b){        pre[a]=b;    }    return ;}bool check(int a,int b){    a=findf(a);    b=findf(b);    if(a==b)        return true;    else        return false;}int main(){    //得到图(结构体数组存边,数组存点)    int n,m;    cin >> n >> m;//不用读入顶点,自动编号    for(int i=1;i<=n;i++){        pre[i]=i;    }    int i;    int sum=0;    int cnt=0;    for(i=1;i<=m;i++){        cin >> edge[i].u >> edge[i].v >> edge[i].w;    }    //建树    sort(&edge[1],&edge[m+1],cmp);//前两个参数是地址,且结束地址要比最后一个元素往后一个,不知为何    //把边先排序    for(i=1;i<=m;i++){//挑最小的边        if(!check(edge[i].u,edge[i].v)){            //判断是否构成圈(并查集)           join(edge[i].u,edge[i].v);    //加入这条边时,才将这个点放入并查集的集合           sum+=edge[i].w;           cnt++;           if(cnt==n-1)                break;  //停止循环条件        }    }    cout << sum ;    return 0;}