这个题与其说是并查集,不如说是最小生成树更准确一点。

做法就是用结构体保存输入,然后按照距离从小到大排序,合并两个点的时候先判断是不是已经在一个集合里了,如果在的话就不用合并,否则合并到一起,然后更新权值。

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
#define max 50*99+10
int pre[110],n,i,j,sum,m;
typedef struct node
{
    int x,y,z;
};
node a[max];
bool cmp(node a,node b)
{
    return a.z < b.z;
}

int find(int x)
{
    int r = x;
    while(r != pre[r])
        r = pre[r];
    int i = x,j;
    while(i != r)
    {
        j = pre[i];
        pre[i] = r;
        i = j;
    }
    return r;
}
void join(int x,int y)
{
    int fx = find(x);
    int fy = find(y);
    pre[fy]=fx;
}
int main()
{
    while(scanf("%d",&n) && n)
    {
        m = n * (n - 1) / 2;
        for(i = 1;i <= n; i++)
            pre[i] = i;
        for(i = 0;i < m; i++)
            scanf("%d %d %d",&a[i].x,&a[i].y,&a[i].z);
        sort(a,a+m,cmp);
        sum = 0;
        for(int i = 0;i < m; i++)
        {
            if(find(a[i].x) != find(a[i].y))
            {
                join(a[i].x,a[i].y);
                sum += a[i].z;
            }
        }
        printf("%d\n",sum);
    }
    return 0;
}