zoukankan      html  css  js  c++  java
  • G

    题目连接 http://acm.hust.edu.cn/vjudge/contest/123674#problem/G

    看到题目的时候是懵逼的,把图一画出来发现就是求最小生成树(现在才觉得离散数学挺重要的),按权值从大到小排序,

    n个点需要添n-1条边。最开始的思路是排序后满足条件的始点和终点最多只有一个出现过一次,不知道是思路不对还是其

    他的总是WA.后来又看书发现书上有模板,运用了并查集,将每个连通分量看成一个集合,集合包含了连通分量里所有的点,

    所有的点都两两想通。

    /*假设i条边的端点序号和权值分别保存在u[i],v[i],w[i],
    r[i]代表中的i代表边的序号(间接排序,排序的关键字是对象的代号
    而不是对象本身)*/
    int com(const int i,const int j)
    {
        return w[i]<w[j];(升序排列)  w[i]>w[j](降序排列)
        
    }
    int find(int x)
    {
        return p[x]==x?x:p[x]=(find(p[x]))//简洁的代码,压缩了路径
    }
    int Kruskal()
    {
        int ans,i;
        for(i=0;i<n;i++) p[i]=i;//点是从0开始的,初始情况下每个根节点都是本身
        for(i=0;i<m;i++) r[i]=i;//初始化边序号
        sort(r,r+m,cmp);
        for(i=0;i<m;i++)
        {
            int e=r[i]; int x=find(u[e]);int y=(find(v[e]));
            if(x!=y)
            {
                ans+=w[e];
                p[x]=y;
            }
        }
    }//注意不能写成p[u[e]]=p[v[e]],因为u[e],v[e],可能不是树根
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define N 105
    #define Ma 5560
    int ptr[N];
    int b[Ma],e[Ma],qu[Ma],r[Ma];
    int com(const int i,const int j)
    {
        return qu[i]<qu[j];//升序排列
    }
    int find(int x)
    {
        return ptr[x]==x?x:ptr[x]=find(ptr[x]);
    }
    void init ()
    {
        //memset(ptr,0,sizeof(ptr));
        memset(b,0,sizeof(b));
        memset(e,0,sizeof(e));
        memset(qu,0,sizeof(qu));
        memset(r,0,sizeof(r));
    }
    int Kruskal(int n,int bi)
    {
        int ans=0;
        int i,j;
        for(i=0;i<n;i++) ptr[i]=i;
        for(j=0;j<bi;j++) r[j]=j;
        sort(r,r+bi,com);//根据权值给边的序号排序
        for(i=0;i<bi;i++)
        {
            int c=r[i];int x=find(b[c]);int y=find(e[c]);
           if(x!=y)
            {
              ans+=qu[c];
               ptr[x]=y;
              
            }
        }
        return ans;
    }
    int main()
    {
        int n,bi;
        while(scanf("%d",&n)&&n)
        {
            init();
            bi=n*(n-1)/2;
            for( int i=0;i<bi;i++)
            {
                scanf("%d %d %d",&b[i],&e[i],&qu[i]);
                b[i]--;//此处容易忽略。点是从1-n
                e[i]--;//而上面的函数却都是从0开始到n-1结束
            }
    
           printf("%d
    ",Kruskal(n,bi));
        }
     return 0;
    }


  • 相关阅读:
    js高级程序设计AJAX && JSON
    python核心高级学习总结7正则表达式
    python核心高级学习总结8动态性、__slots__、生成器、迭代器、装饰、闭包
    python核心高级学习总结3python实现进程的三种方式及其区别
    python核心高级学习总结6面向对象进阶之元类
    运维术语名词
    资源分享编程、数据库、安全、运维等
    python之Bug之字符串拼接bug
    CSS hack:实现IE6、IE7、Firefox兼容(转摘)
    (装载) Web开发技术的历史发展简介
  • 原文地址:https://www.cnblogs.com/Twsc/p/5702943.html
Copyright © 2011-2022 走看看