zoukankan      html  css  js  c++  java
  • 最小生成树(改了两个板子写的)道路建设

    题目:

    https://www.nowcoder.com/acm/contest/76/B

    链接:https://www.nowcoder.com/acm/contest/76/B
    来源:牛客网

    随着如今社会的不断变化,交通问题也变得越来越重要,所以市长决定建设一些公路来方便各个城市之间的贸易和交易。虽然市长的想法很好,但是他也遇到了一般人也经常头疼的问题,那就是手头的经费有限……在规划过程中,设计师们已经预算出部分城市之间建设公路的经费需求。现在市长想知道,它能不能将他的m个城市在有限的经费内实现公路交通。如果可以的话,输出Yes,否则输出No(两个城市不一定要直接的公路相连,间接公路到达也可以。)

    输入描述:

    测试输入包含多条测试数据
    每个测试数据的第1行分别给出可用的经费c(<1000000),道路数目n(n<10000),以及城市数目m(<100)。
    接下来的n行给出建立公路的成本信息,每行给出三个整数,分别是相连的两个城市v1、v2(0<v1,v2<=m)以及建设公路所需的成本h(h<100)。

    输出描述:

    对每个测试用例,输出Yes或No。

    示例1

    输入

    20 10 5
    1 2 6
    1 3 3
    1 4 4
    1 5 5
    2 3 7
    2 4 7
    2 5 8
    3 4 6
    3 5 9
    4 5 2

    输出

    Yes
    示例2

    输入

    10 2 2
    1 2 5
    1 2 15

    输出

    Yes

    备注:

    两个城市之间可能存在多条线路



    题意: 将所有的城市连接起来求最小的花费是否小于总价c


    思路:

    最小生成树问题:求出最小的花费就ok

    ps:    如果不能把所有的城市连接起来就算no

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<algorithm>
    #include<map>
    #define maxn 50010
    using namespace std;
    int par[maxn];
    int ranke[maxn];
    void init(int n)
    {
        for(int i=0;i<n;i++){
            par[i]=i;
            ranke[i]=0;
        }
    }
    int find(int x)//找父亲
    {
        if(par[x]==x)return x;
        else {
            return par[x]=find(par[x]);//递归找父亲(因为父亲是统一的)
        }
    }
    void unite(int x,int y)
    {
        x=find(x);
        y=find(y);
        if(x==y)return ;
        if(ranke[x]<ranke[y])
        {
            par[x]=y;
        }
        else par[y]=x;
        if(ranke[x]==ranke[y])ranke[x]++;
    }
    bool same(int x,int y)
    {
        return find(x)==find(y);
    }
     
     
    struct edge{
      int from,to,cost;
    };
    bool comp(const edge& e1,const edge& e2)
    {
        return e1.cost<e2.cost;
    }
    edge mp[maxn];
    int V,E;
    int res;
    int flag;
    int kruskal()
    {
        flag=1;
        sort(mp,mp+E,comp);
        init(V);
        res=0;
        for(int i=0;i<E;i++)
        {
            edge s=mp[i];
            if(!same(s.from,s.to)){
                unite(s.from,s.to);
                flag++;
            res+=s.cost;
            }
        }
        return res;
    }
    int main()
    {
        int d1,d2,dis;
       int mon;
       while(cin>>mon>>E>>V)
       {
           for(int i=0;i<E;i++)
           {
               cin>>d1>>d2>>dis;
               d1--;
               d2--;
                mp[i].from=d1;
                mp[i].to=d2;
                mp[i].cost=dis;
           }
            kruskal();
            //cout<<flag;
            if(flag!=V)cout<<"No"<<endl;
           else
           {
               if(res>mon)cout<<"No"<<endl;
               else cout<<"Yes"<<endl;
           }
        }
        return 0

    题目很简单,本来早就可以出的,但是由于题目理解错误还有没有考虑   ps   的那种情况使这题晚了半小时出,,怎么说呢,本来学了这么久的图论树论这场可以打个很好的成绩的,还是需要努力啊,毕竟这个实力太弱了了,图论的题目还是要多刷,多藏些板子。

    还有一个学期,加油吧

  • 相关阅读:
    Note/Solution 转置原理 & 多点求值
    Note/Solution 「洛谷 P5158」「模板」多项式快速插值
    Solution 「CTS 2019」「洛谷 P5404」氪金手游
    Solution 「CEOI 2017」「洛谷 P4654」Mousetrap
    Solution Set Border Theory
    Solution Set Stirling 数相关杂题
    Solution 「CEOI 2006」「洛谷 P5974」ANTENNA
    Solution 「ZJOI 2013」「洛谷 P3337」防守战线
    Solution 「CF 923E」Perpetual Subtraction
    KVM虚拟化
  • 原文地址:https://www.cnblogs.com/huangzzz/p/8444237.html
Copyright © 2011-2022 走看看