克鲁斯卡尔算法(模板)

/*

INPUT

6
10
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6


OUTPUT

15

*/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N=1e5;
struct node
{
    int u,v,w;
    bool operator<(const node &C)const
    {
        return w<C.w;//表示以w从小到大排序
    }
}t[N];
int n,m;
int p[1001];
int cha(int x)
{
    //return x==p[x]?p[x]:cha(p[x]);
    if(x!=p[x])
    {
        p[x]=cha(p[x]);//一直找到祖先
    }
    return p[x];

}
int cl()
{
    int sum=0,top=0;
    for(int i=0;i<m;i++)//从第一条边开始遍历
    {
        int x=t[i].u;
        int y=t[i].v;
        x=cha(x);
        y=cha(y);
        if(x!=y)//假如不是同一祖宗,就连,如果是同一个祖宗也连的话,就会形成回路
        {
            p[x]=y;//则将其中一个点作为另一个点的祖宗,就把点与点连起来了
            sum+=t[i].w;
            top++;//累计连接线的条数
        }
        if(top==n-1) return sum;//要使n个点全部连通,至少需要n-1条边
    }
    return -1;//无法连通
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)//n个点,m条边
    {
        for(int i=1;i<=n;i++)
            p[i]=i;//并查集 开始全部初始化为本身
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&t[i].u,&t[i].v,&t[i].w//分别代表起点,终点,权值
        }
        sort (t,t+m);//保证后面取数都是目前最小的
        printf("%d
",cl());
    }
    return 0;
}
原文地址:https://www.cnblogs.com/tianmin123/p/4766972.html