zoukankan      html  css  js  c++  java
  • [ACM

    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
    Hint
    Hint
    Huge input, scanf is recommended.
     

    Source


    解题思路:

    昨天看了并查集和最小生成树,好不容易搞懂了,今天做了这道典型的最小生成树题目,一次Ac,挺高兴的。把每个村庄看成一个节点,从1开始编号,然后把每条边从小到大排序,一开始一条边也没有,每个村庄是一个独立的集合,构造最小生成树时从最小边开始添加边,添加的时候每次都需要判断边两端的节点(村庄编号)是否有相同的根节点,如果有则不能添加(构成回路),如果没有则该边添加。

    代码:

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    struct Node
    {
        int u,v;
        int len;
    }node[5000]; //每条边是一个结构体,u,v分别为边两头的点,len为边的长度
    
    int parent[103];//村庄的个数,节点
    
    void init(int n)
    {
        for(int i=1;i<=n;i++)
            parent[i]=i;//初始化 ,一开始每个村庄都是一个单独的集合,编号从1到n 
    }
    
    bool cmp(Node a,Node b)
    {
        if(a.len<b.len)
            return true;
        return false;
    } //按边的长短从小到大排序
    
    int find(int x)
    {
        return parent[x]==x?x:find(parent[x]);//找根结点,如2的父节点是3,再找3的父节点是几,直到x的根节点为x为止
    }
    
    int main()
    {
        int m,n,i;
        while(cin>>m&&m)
        {
            int cost=0;
            n=m*(m-1)/2;//边的条数,题目中
            init(m);
            for(i=1;i<=n;i++)
                cin>>node[i].u>>node[i].v>>node[i].len;
            sort(node+1,node+1+n,cmp);
            for(i=1;i<=n;i++)
            {
                int x=find(node[i].u);
                int y=find(node[i].v);
                if(x==y)
                    continue;
                parent[y]=x;//这里是把x当作了整棵最小生成树的根节点,写成parent[x]=y也可以,根节点换成了y,这里的x,y值都不会大于村庄的编号
                cost+=node[i].len;
            }
            cout<<cost<<endl;
        }
        return 0;
    }
    


  • 相关阅读:
    archlinux .bash_history
    Ubuntu环境下挂载新硬盘
    软碟通 UltraISO U启替代品 Win32DiskImager 无设备 无盘符 无u盘 无优盘 解决方案 之diskpart
    delphi Integer overflow
    MSBuild Tools offline
    delphi synedit免费的拼写检查器dll
    git 自定义命令行
    lua编译
    gcc ar
    Windows Subsystem for Linux (WSL)挂载移动硬盘U盘 卸载 c d 盘
  • 原文地址:https://www.cnblogs.com/sr1993/p/3697819.html
Copyright © 2011-2022 走看看