• HDU-1233-还是畅通工程(最小生成树kruscal)


    还是畅通工程

    Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 45838 Accepted Submission(s): 20885

    Problem Description
    某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。

    Input
    测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。
    当N为0时,输入结束,该用例不被处理。

    Output
    对每个测试用例,在1行里输出最小的公路总长度。

    Sample Input
    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

    Sample Output
    3
    5

    #include<stdio.h>///kruscal算法
    #include<algorithm>
    using namespace std;
    struct Road///包括这条边是从哪儿(from)到(to)哪儿,以及长度(val)
    {
        int x,y,dis;
    } road[10000];
    bool cmp(Road a,Road b)///结构体排序
    {
        return a.dis<b.dis;///给长度按从小到大排序
    }
    int finds[150];
    int Find(int n)///并查集的查找函数
    {
        return finds[n]==n?n:Find(finds[n]);
    }
    void join(int x,int y)///合为一个集合中
    {
        finds[Find(x)]=Find(y);
    }
    int main()
    {
        int n,i,j;
        while(scanf("%d",&n)!=EOF)///n个城镇,m条边
        {
            if(!n)break;
            int m=n*(n-1)/2;///这里是边的数量
            for(i=0; i<m; i++)///输入从哪儿到哪儿,这里不是利用邻接矩阵了,直接给边赋予信息
            {
                scanf("%d%d%d",&road[i].x,&road[i].y,&road[i].dis);
            }
            sort(road,road+m,cmp);///给边按从小到大排序
            for(i=0; i<=n; i++)///预处理
            {
                finds[i]=i;
            }
            int sum=0,flag=0;
            for(i=0; i<m; i++)///从长度小的边开始遍历
            {
                if(Find(road[i].x)!=Find(road[i].y))///第一小的边的开始和结尾上司不同
                {///这里如果他们的上司不一样,说明他们之间没有连通,不会构成环状,可以选择这条边加上
                    flag++;///已经加入的边计数
                    join(road[i].x,road[i].y);///并把相应节点合为一个集合(表示已经连通)
                    sum+=road[i].dis;///总长度加上这条边
                }///再找下一个短边的两个城镇是否连通,没连通则将其连通,总和加上那条边的长度
                if(flag==m-1)break;///记住这里是边的数量,m的数量,不是n的数量
            }///因为n个城镇不会超过n-1条边,因此当达到这个边数目时就可以跳出了,此时总和就是所有最短边总和
            printf("%d
    ",sum);
        }
        return 0;
    }
    
  • 相关阅读:
    linux环境下Redis主从复制和集群环境搭建
    2017年秋季学期软件工程第二次作业
    《人月神话》读后感
    功能需求描述
    初学Windows应用程序开发遇到的几个专业名词解释
    2017年秋季学期软件工程第一次作业(曹洪茹)
    第二次四则运算完善
    《人月神话》读后感
    软件工程课上随笔-规约
    2017软件工程第三次作业
  • 原文地址:https://www.cnblogs.com/kuronekonano/p/11794355.html
Copyright © 2020-2023  润新知