zoukankan      html  css  js  c++  java
  • Just oj 2018 C语言程序设计竞赛(高级组)F:Star(结构体排序+最小生成树)

    F: Star

    Time Limit: 1 s      Memory Limit: 128 MB     

    Submit My Status

    Problem Description

           31世纪,人类世界的科技已经发展到了空前的高度,星际移民,星际旅游早已经不再是问题。人类已经掌握了开发星系的能力。但是,无论发展到何种地步,资源一直是人们关注的重点。一种新的能源被人类掌握,通过它可以搭建虫洞,实现超光年传输。发展武器。但是虽然这种物质在宇宙海量的存在着,但它对于宇宙的稳定是至关重要的,若过量消耗这种物质,对于宇宙的稳定,星系与星系之间以及星系内部的微妙平衡都会产生巨大的影响。这种物质就是暗物质。

                                                                                                                                                                                                                -----《宇宙百科》节选

           现在,你所在的星系下有nn个主星球居住着人民。为了星系内部的稳定与和平发展,现在需要在nn个主星球之间建立空间虫洞,众所周知建立虫洞要消耗大量的暗物质,因此,你想要在nn个主星球之间建立联系的情况下尽量少的消耗暗物质。目前你已经知道的是,建立虫洞所需要消耗的暗物质与两个星球之间的距离成正比,比例系数为kk。并且,两个星球之间的距离为空间缩点距离。每个星球有它自己的三维物理坐标。不过,现在有一个好消息。你所在的星系掌握了一项新的技术,空间奇点压缩,简单来说就是降维,但是由于技术发展初期不够成熟,只能压缩一维。并且,任意两个主星球之间都可以选择是否进行空间奇点压缩。现在,你想知道,在这n个主星球之间建立连接需要花费的最少暗物质是多少。

         空间缩点距离:设两个nn维坐标a(x1,x2,x3,,,,xn),b(y1,y2,y3,y4,,,yn)a(x1,x2,x3,,,,xn),b(y1,y2,y3,y4,,,yn).设距离为ss,则s=abs((x1+x2+x3+…+xn)−(y1+y2+y3+…+yn))s=abs((x1+x2+x3+…+xn)−(y1+y2+y3+…+yn));

                                                                                                                                                                                       ----以上内容纯属瞎扯,请忽略其真实性

    Input

    第一行两个整数nn和kk。(1≤n≤105,1≤k≤103)(1≤n≤105,1≤k≤103)

    接下开nn行,每行三个整数x,y,zx,y,z,其中第ii行表示第ii个星球在星系中的物理坐标。数据保证没有两个星球处于同一个位置上。(1≤x,y,z≤106)(1≤x,y,z≤106)

    Output

    nn个主星球之间建立连接需要花费的最少暗物质。

    Sample Input

    3 2
    1 1 6
    1 2 9
    3 20 8
    

    Sample Output

    4
    

    Hint

    样例说明:

    星球1和星球2之间压缩第三维

    星球2和星球3之间压缩第二维

    题解:通过排序找出不压缩、压缩X、压缩Y、压缩Z四种情况中相邻最近的两点,然后算出压缩后折算的距离并记录下来
    然后再次排序,依次枚举直到连接完所有点,连接边长度的总和即为总距离,从而求出所需的暗物质

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #define maxn 100007
    using namespace std;
    int n,k,cnt;
    int f[maxn];
    struct sta{
            int x,y,z,id;
    }s[maxn];
    struct P{
            int st,ed,dis;
            bool operator<(const P &a)const{
                    return dis<a.dis;
            }
    }p[maxn*4];
    bool xyz(sta a,sta b){
            return a.x+a.y+a.z<b.x+b.y+b.z;
    }
    bool xy(sta a,sta b){
            return a.x+a.y<b.x+b.y;
    }
    bool yz(sta a,sta b){
            return a.y+a.z<b.y+b.z;
    }
    bool xz(sta a,sta b){
            return a.x+a.z<b.x+b.z;
    }
    void init()
    {
            cnt=0;
            sort(s,s+n,xyz);
            for(int i=1;i<n;i++)
                    p[cnt++]={s[i].id,s[i-1].id,s[i].x+s[i].y+s[i].z-(s[i-1].x+s[i-1].y+s[i-1].z)};
            sort(s,s+n,xy);
            for(int i=1;i<n;i++)
                    p[cnt++]={s[i].id,s[i-1].id,s[i].x+s[i].y-(s[i-1].x+s[i-1].y)};
            sort(s,s+n,yz);
            for(int i=1;i<n;i++)
                    p[cnt++]={s[i].id,s[i-1].id,s[i].y+s[i].z-(s[i-1].y+s[i-1].z)};
            sort(s,s+n,xz);
            for(int i=1;i<n;i++)
                    p[cnt++]={s[i].id,s[i-1].id,s[i].x+s[i].z-(s[i-1].x+s[i-1].z)};
            sort(p,p+cnt);
    }
    int find(int x){
            return f[x]=(x==f[x]?x:find(f[x]));
    }
    void kruskal()//找寻n个点连接的n-1条边的最小和(最小生成树)
    {
            for(int i=0;i<=n;i++)
                    f[i]=i;
            int ans=0,num=n-1;//n-1条树枝
            for(int i=0;i<cnt&&num;i++)
            {
                    int a=find(p[i].st);
                    int b=find(p[i].ed);
                    if(a!=b){
                            f[a]=b;
                            num--;
                            ans+=p[i].dis;
                    }
            }
            printf("%d
    ",ans*k);
    }
    int main()
    {
            scanf("%d%d",&n,&k);
            for(int i=0;i<n;i++)
                    scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].z),s[i].id=i+1;
            init();
            kruskal();
            return 0;
    }
  • 相关阅读:
    js基础 数组reduce
    js基础 数组every some
    js基础 数组forEach
    js基础 数组排序
    js基础 数组findIndex
    nodejs+koa2微信app支付,小程序支付
    Iview-datePicker获取选中的日期,如果没有选,提示错误,选了,错误隐藏
    mongoose+koa2 按照_id更新多条数据,删除数组中的字段,然后添加新的字段,$pull和$or结合使用
    json数组去除重复的值
    mongoose根据_id更新,且如果数组中没有元素就添加
  • 原文地址:https://www.cnblogs.com/aeipyuan/p/10182221.html
Copyright © 2011-2022 走看看