【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; }