【8.5测试】卫星

                         卫星
【题目背景】
传说很久很久以前,天上有 n 颗星星。
【问题描述】
由于宇宙是个3维空间,所以每颗星星的坐标有4个参数(雾)。第 i 颗星星
的坐标为 (x[i],y[i],z[i],w[i])。伟大的拉面之神掌握着一种秘技:降维打
击,使得第 i 颗星星和第 j 颗星星之间的距离为
min(|x[i]-x[j]|,|y[i]-y[j]|,|z[i]-z[j]|,|w[i]-w[j]|)
拉面之神想要在一些星星之间建双向道路,代价为两颗星星间的距离,使得
任意两个星星之间可以互相到达。作为拉面之神,自然数学高达小学四年级水
平,他想烤烤你,最小的代价是多少。
【输入格式】
第 1 行 1 个整数 n ,表示有 n 颗星星。
接下来 n 行,每行 4 个整数 x[i],y[i],z[i],w[i] ,表示第 i 颗星星的坐
标。
【输出格式】
一个整数,表示最小的代价。
【样例输入】
4
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
【样例输出】
12
【数据范围】
序号 n
1 10
2 123
3 456
4 789
5 1888
6 2000
7 50000
8 100000
9 150000
10 150000
所有的数据及答案均为不超过 long long 范围的非负整数

题解:四次排序,4维降一维。每次排序都能保证连接相邻的点

          就是要求不许建n*n条边,不然建边就超时了。。。。

#include <bits/stdc++.h>

using namespace std;
#define mmst(a, b) memset(a, b, sizeof(a))
#define mmcp(a, b) memcpy(a, b, sizeof(b))

typedef long long LL;

const int N=150010;

int n,fa[N];
int cnt;
LL ans;

struct yy
{
    int x,y,z,w,num;
}f[N];

struct edge
{
    int u,v;
    LL w;
}a[N<<2];

LL dis(yy a,yy b)
{
    LL o=min(abs(a.x-b.x),abs(a.y-b.y));
    LL p=min(abs(a.z-b.z),abs(a.w-b.w));
    return min(o,p);
}

int find(int x)
{
    if(fa[x]!=x)
    fa[x]=find(fa[x]);
    return fa[x];
}

bool cmp1(yy a,yy b)
{
    return a.x<b.x;
}

bool cmp2(yy a,yy b)
{
    return a.y<b.y;
}

bool cmp3(yy a,yy b)
{
    return a.z<b.z;
}

bool cmp4(yy a,yy b)
{
    return a.w<b.w;
}

bool cc(edge a,edge b)
{
    return a.w<b.w;
}

int main()
{
    freopen("planet10.in", "r", stdin);
    freopen("planet10.ans", "w", stdout);
    
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d%d",&f[i].x,&f[i].y,&f[i].w,&f[i].z);
        f[i].num=i;
    }
    
    sort(f+1,f+n+1,cmp1);
    for(int i=2;i<=n;i++)
    {
        a[++cnt].u=f[i-1].num;
        a[cnt].v=f[i].num;
        a[cnt].w=dis(f[i-1],f[i]);
    }
    
    sort(f+1,f+n+1,cmp2);
    for(int i=2;i<=n;i++)
    {
        a[++cnt].u=f[i-1].num;
        a[cnt].v=f[i].num;
        a[cnt].w=dis(f[i-1],f[i]);
    }
    
    sort(f+1,f+n+1,cmp3);
    for(int i=2;i<=n;i++)
    {
        a[++cnt].u=f[i-1].num;
        a[cnt].v=f[i].num;
        a[cnt].w=dis(f[i-1],f[i]);
    }
    
    sort(f+1,f+n+1,cmp4);
    for(int i=2;i<=n;i++)
    {
        a[++cnt].u=f[i-1].num;
        a[cnt].v=f[i].num;
        a[cnt].w=dis(f[i-1],f[i]);
    }
    
    
    for(int i=1;i<=n;i++)
    fa[i]=i;
    
    sort(a+1,a+cnt+1,cc);
    
    for(int i=1;i<=cnt;i++)
    if(find(a[i].u)!=find(a[i].v))
    {
        ans+=a[i].w;
        fa[fa[a[i].u]]=a[i].v;
    }
    
    cout<<ans<<endl;
    
    return 0;
}
原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11307922.html