zoukankan      html  css  js  c++  java
  • [ACM] hud 还是畅通工程(重写)

    还是畅通工程



    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
     

    Recommend
    JGShining   |   We have carefully selected several similar problems for you:  1232 1102 1875 1879 1301 


    心得:

    这题本质是求最小生成树,其中用到了并查集。这题以前做过,那时候是一次AC的,今天重写一次,错误百出,改了好久(详见代码注释),通过这次重写,对最小生成树的执行过程有了巩固和提高,对并查集的使用也有了一定的理解。

    代码:

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
    int parent[102],n;
    struct Node
    {
        int s,e,len;
    }node[5002];
    
    bool cmp(Node a,Node b)
    {
        if(a.len<b.len)
            return true;
        return false;
    }
    
    void init(int n)
    {
        for(int i=1;i<=n;i++)
            parent[i]=i;//犯得第一个错误,一开始写成parent[i]=0;初始化,每个村庄的根节点应该是自己的编号
    }
    int find(int x)
    {
        return parent[x]==x?x:find(parent[x]);
    }
    
    void unite(int x,int y)
    {
        x=find(x);
        y=find(y);
        if(x==y)
            return ;
        else
            parent[x]=y;
    }
    bool unsame(int x,int y)
    {
        if(find(x)==find(y))
            return false;//犯得第三个错误,当两个村庄没有共同根节点时才相加其len
        return true;
    }
    int main()
    {
        while(cin>>n&&n)
        {
    
            int m=n*(n-1)/2;
            init(n);//犯得第四个错误,初始化是对村庄的编号进行初始化,n应该是村庄的个数,而不是路的个数。
            int length=0;
            for(int i=1;i<=m;i++)
                scanf("%d%d%d",&node[i].s,&node[i].e,&node[i].len);
            sort(node+1,node+1+m,cmp);//犯得第二个错误,对节点的个数排序,千万注意这里的节点不是村庄还是村庄之间的路。
    
            for(int i=1;i<=m;i++)
            {
                //第一种解法
    
                //if(unsame(node[i].s,node[i].e))
                 //   length+=node[i].len;
                //unite(node[i].s,node[i].e); //犯得第五个错误,把unie写在了前面,如果那样,先连接村庄,下一句判断那么两个村庄必定有相同的根节点(二者之一),造成length+=node[i].len;每次循环都执行,必定错误。
    
                //第二种解法
                int a=find(node[i].s);
                int b=find(node[i].e);
                if(a==b)
                    continue;
                parent[a]=b;
                length+=node[i].len;
            }
            cout<<length<<endl;
        }
        return 0;
    }
    


    运行:



  • 相关阅读:
    [转载]解决zabbix在configure时候遇到的问题(Ubuntu)
    [转载]ubuntu的版本
    [转载]Nginx如何处理一个请求
    微信小程序—文件系统
    javascript 中 x offsetX clientX screenX pageX的区别
    Bootstrap 框架、插件
    HTML自定义滚动条(仿网易邮箱滚动条)转载
    Vue 组件(上)转载
    vue $mount 和 el的区别
    $on在构造器外部添加事件$once执行一次的事件$off关闭事件
  • 原文地址:https://www.cnblogs.com/sr1993/p/3697793.html
Copyright © 2011-2022 走看看