hdu_1863 畅通工程

来源:岁月联盟 编辑:exp 时间:2012-08-05

TimeLimit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 8916 Accepted Submission(s): 3454

ProblemDescription
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
 
Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M (< 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
 
Output
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
 
SampleInput
3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100
 
SampleOutput
3
?
解题思路:
这一题是一个典型的并查集案例题,这一题主要的解题思路是用刚学的并查集的示例代码来实现的。用一个findSet(int x)函数来查找x节点的根节点,返回该跟节点的下标
用一个结构体array来表示某个节点的值,值x城市到y城市之间的距离为z,输入的时候,先将输入的路线按照城市与城市之间的距离z进行排序,连接的时候将结构体array数组的值作为该下标的父节点,这样进行递归查找,当路线的条数等于城市数-1是就输出,如果到最后建立起来的数的路线总数小于路线的条数等于城市数-1,也表示不可达
代码实现:
#include <stdio.h> 
#include<iostream> 
#include <algorithm> 
using namespace std; 
int set[102];//每个节点,现在是一颗只有一个节点的树 
struct array { 
    int x; 
    int y; 
    int z; 
}; 
int findSet(int x) {//查找x节点的根节点 
    if (x == set[x]) {//返回该下标 
        return x; 
    } else { 
        return set[x] = findSet(set[x]); 
    } 

int main() { 
    int n, m; 
    int count = 0;//计算总路线数量,n个节点n-1条边 
    int sum = 0;//总价 
    int i,j; 
    array a[100]; 
    array temp; 
    //array a[100]; 
    while (scanf("%d", &n)) { 
        if (n != 0) {//输入不为0时 
            sum = 0; 
            count = 0; 
            scanf("%d", &m); 
            for (i = 1; i <= n; i++) { 
                set[i] = i; 
                scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z); //第一个村庄a[i].x与第二个村庄a[i].y之间的距离a[i].z 
            } 
            for (i = 1; i <= n; i++) { 
                for (j = i + 1; j <= n; j++) {//从小到大排序 
                    if (a[i].z > a[j].z) { 
                        temp = a[i]; 
                        a[i] = a[j]; 
                        a[j] = temp; 
                    } 
                } 
            } 
            for (i = 1; i <= n; i++) { 
                int fx = findSet(a[i].x); 
                int fy = findSet(a[i].y); 
                if (fx==fy) {//有相同的父节点,则不用在连接了 
                    continue; 
                } else {//连接两个节点 
                    set[fx] = fy ; 
                    count++;//路线总数 
                    sum += a[i].z; 
                } 
                if (count == m - 1) { 
                    break; 
                } 
            } 
            if(count<m-1) 
            {//输出不符合情况 
                printf("?/n"); 
            } 
            else//输出总和 
                printf("%d/n", sum); 
        } else { 
            break; 
        } 
    } 
    return 0; 


作者:CSDN515