• 24.最优布线问题(kruskal算法)


    时间限制: 1 s

     空间限制: 128000 KB

     题目等级 : 白银 Silver

    题解

     查看运行结果

    题目描述 Description

    学校需要将n台计算机连接起来,不同的2台计算机之间的连接费用可能是不同的。为了节省费用,我们考虑采用间接数据传输结束,就是一台计算机可以间接地通过其他计算机实现和另外一台计算机连接。

    为了使得任意两台计算机之间都是连通的(不管是直接还是间接的),需要在若干台计算机之间用网线直接连接,现在想使得总的连接费用最省,让你编程计算这个最小的费用。

    输入描述 Input Description

    输入第一行为两个整数n,m2<=n<=1000002<=m<=100000),表示计算机总数,和可以互相建立连接的连接个数。接下来m行,每行三个整数a,b,c 表示在机器a和机器b之间建立连接的话费是c(题目保证一定存在可行的连通方案, 数据中可能存在权值不一样的重边,但是保证没有自环)

    输出描述 Output Description

    输出只有一行一个整数,表示最省的总连接费用。

    样例输入 Sample Input

    3 3

    1 2 1

    1 3 2

    2 3 1

    代码:

    #include

    using namespace std;

    #include

    #include

    #include

    #define maxn 100001

    #define INF 0x7fffffff

    int n,m,a,b,c;

    long long tot=0;//long long 才能存下

    int father[maxn]={0};

    struct Edge{

           int u,v,w,next;

    };

    Edge edge[maxn];

    void input();

    void krsual();

    int main()

    {

           input();

           krsual();

           printf("%lld ",tot);

           return 0;

    }

    int cmp(const Edge &a,const Edge &b)

    {

           return a.w

    }

    void input()

    {

           scanf("%d%d",&n,&m);

           for(int i=1;i<=m;++i)

           edge[i].w=INF;

           for(int i=1;i<=m;++i)

           {

                  scanf("%d%d%d",&a,&b,&c);

                  if(edge[i].w>c)

                  {

                         edge[i].w=c;

                         edge[i].u=a;

                         edge[i].v=b;

                  //     edge[i+m].w=c;(处理无向图的边表,都加m就可以了)

                  //     edge[i+m].v=a;

                  //     edge[i+m].u=b;

                  }

           }

    }

    int find(int x)

    {

           if(father[x]!=x) father[x]=find(father[x]);

           return father[x];

    }

    void unionn(int r1,int r2)

    {

           father[r2]=r1;

    }

    int k=0;

    void krsual()

    {

                  for(int i=1;i<=n;++i)

                father[i]=i;

               sort(edge+1,edge+m+1,cmp);

               for(int i=1;i<=m;++i)//把所有的边都遍历一遍

               {

                      int r1=find(edge[i].u);

                      int r2=find(edge[i].v);

                      if(r1!=r2)//注意并查集合并和查找都是找的集合的代表元素

                      {

                             unionn(r1,r2);//不是合并两个点,是合并代表元素

                             tot+=edge[i].w;

                             k++;

                             if(k==n-1) return ;//计数,n-1条边就够了

                            

                         }

                  }

    }

  • 相关阅读:
    Android性能优化典范(转)
    java分形树
    android通过pc脚本执行sqlite3脚本
    针对JD-GUI
    三星的中低端机使用AsyncTask的问题
    Github简明教程(转)
    android 5.0 (lollipop)源码编译环境搭建(Mac OS X)
    排队接水
    幂次方
    2020/4/12
  • 原文地址:https://www.cnblogs.com/csgc0131123/p/5290498.html
Copyright © 2020-2023  润新知