zoukankan      html  css  js  c++  java
  • VIJOS-P1045 Kerry 的电缆网络

    JDOJ 1229: VIJOS-P1045 Kerry 的电缆网络

    https://neooj.com/oldoj/problem.php?id=1229

    Description

            Kerry  是德国的一位电缆商人。因联合国脱贫计划的邀请,他准备负责在土鲁齐亚埃萨亚克斯乌托斯邦建立电缆网络,以满足这个国家的用电需求。当然,现在土鲁齐亚埃萨亚克斯乌托斯邦没有任何电缆。已知土鲁齐亚埃萨亚克斯乌托斯邦一共有n个城镇,已经编号为1到n。其中任意两个城镇可能有一条路,也可能没有。如果两个城镇之间有一条路pi,那么这条路有一个长度si,则Kerry可以在这两个城市之间建立一条电缆线,电缆线的长度也就是这条路的长度si。         现在Kerry准备了s长的电缆线,电缆线可以任意拆断,拆断不损失任何电缆线。他需要将土鲁齐亚埃萨亚克斯乌托斯邦所有城镇都能够连入这个电缆网络。那么,Kenny能不能使用这s长度的电缆线完成这项工作;如果能够完成,那么Kerry最少耗用多少长度的电缆线呢?

    Input

            第一行一个正实数S;         第二行一个正整数n;         接下来一共有m行,第i行有两个整数xi,yi和一个实数si,表示编号为xi个村庄和编号为yi个村庄之间有一条路,路的长度为si。         输入保证xi不等于yi,两个城镇之间不会有两条路。

    Output

    若能够完成(建立这样的电缆网络),则输出(其中< X> 代表最少的电缆线长度,保留两位小数): Need  < X>   miles  of  cable 否则输出: Impossible

    Sample Input

    100.0 4 1 2 2.0 1 3 4.2 1 4 6.7 3 4 4.0 2 4 10.0

    Sample Output

    Need 10.20 miles of cable

    HINT

    1< =n,m< =100000 

    复习KRUSKAL算法的一道板子题。

    用这道题简单介绍一下KRUSKAL算法。

    实现原理我觉得是图论算法中最简单的一个。

    不是要求最小生成树么?

    好,我把边按照边权从小到大排序,当然也可以求最大生成树,从大到小排序不就可以了?

    排序完了之后依次枚举每条边,加入到最小生成树中,这里要注意了,我们不能乱加,需要判断加进去的这条边能不能和已经加进去的边构成树,显然的,如果加进去的边和其他的边构成了环,那么就肯定不能把这条边加进树中,我们需要判断能不能构成环,就使用并查集维护即可(即并查集判环)。

    有了这些理论知识,AC这道题就很简单了。

    Code:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,x,y,j,cnt;
    double s,z,ans;
    int fa[100010];
    struct city
    {
        int x,y;
        double z;
    }e[1000010];
    bool cmp(city a,city b)
    {
        return a.z<b.z;
    }
    int find(int x)
    {
        if(fa[x]==x)    return x;
        return fa[x]=find(fa[x]);
    }
    int main()
    {
        scanf("%lf%d",&s,&n);
        while(scanf("%d%d%lf",&x,&y,&z)!=EOF)
        {
            j++;
            e[j].x=x;e[j].y=y;e[j].z=z;
        }
        sort(e+1,e+j+1,cmp);
        for(int i=1;i<=n;i++)
            fa[i]=i;
        for(int i=1;i<=j;i++)
        {
            int fx=find(e[i].x);
            int fy=find(e[i].y);
            if(fx!=fy)
            {
                fa[fx]=fy;
                cnt++;
                ans+=e[i].z;
            }
            if(cnt==n-1)
                break;
        }
        if(ans<=s && cnt==n-1)
            printf("Need %.2lf miles of cable",ans);
        else
            printf("Impossible");
        return 0;
    }
  • 相关阅读:
    C# linq根据属性分组,并累加计算
    AR模板分组显示(C#打印)
    显示单据信息(类似打印)
    C#同步方法中调用异步方法
    win10 Git安装或者使用出现128问题
    简单的分页查询实现
    数据库批量插入【数据库】
    VideoView
    音乐播放
    画画板案例
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11172543.html
Copyright © 2011-2022 走看看