蓝桥杯 历届试题 还是畅通工程

首先了解什么是并查集:

并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。集就是让每个元素构成一个单元素的集合,也就是按一定顺序将属于同一组的元素所在的集合合并。在一些有N个元素的集合应用问题中,通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学的国际国内赛题中,其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往在空间上过大,计算机无法承受;即使在空间上勉强通过,运行的时间复杂度也极高。

题目:

某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),
并要求铺设的公路总长度为最小。请计算最小的公路总长度。
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
当N为0时,输入结束,该用例不被处理。
对每个测试用例,在1行里输出最小的公路总长度。
例如:
用户输入:
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
则,程序应该输出:
3
5
资源约定:
峰值内存消耗 < 256M
CPU消耗  < 2000ms

分析:

并查集主要就是解决不相交的问题,判断两个个体是否有关联,如果没有,设法关联首先用p数组初始化个体,定义相互之间没有关联,然后输入数据,循环判断各组数据的关系,对于间接有关系的数据,用查找函数递归实现关联,对没有关联的数据用合并函数进行关联。最后构成一个相互之间有关联的网状树形结构。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct T
{
    int x,y,z;
    bool operator<(const T &p)const
    {
        return z<p.z;
    }
} a[110];
int n,p[110],s;
int chazhao(int x)
{
    if(p[x]==x)
        return x;
    else
        return chazhao(p[x]);
}
void  hebing(int x,int y,int c)
{
    int f1=chazhao(x);
    int f2=chazhao(y);
    if(f1!=f2)
    {
        s+=a[c].z;
        p[f1]=f2;
    }
}
int main()
{
    int i,j,m;
    while(scanf("%d",&n)&&n!=0)
    {
        for(i=1;i<n;i++)
            p[i]=i;
        s=0;
        m=n*(n-1)/2;
        for(i=0; i<m; i++)
            scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
        sort(a,a+m);
        for(i=0; i<m; i++)
            hebing(a[i].x,a[i].y,i);
        printf("%d\n",s);
    }
    return 0;
}





你可能感兴趣的:(蓝桥杯 历届试题 还是畅通工程)