【洛谷P8191】Moo Network G
P8191 [USACO22FEB] Moo Network G
题目描述
农夫约翰有 \(N\) 头牛(\(1\le N\le10^5\)) 它们在农场里分布的极其的远,因此希望你建立一个通讯网络,便于它们更容易地交换电子短信(当然,这些短信都包含 moo 的变形体,即数字)
第 \(i\) 头牛位于位置 \((x_i,y_i)\) 其中 \(0\le x\le 10^6\), \(0\le y\le 10\). 在牛 \(i\) 与牛 \(j\) 之间建立通信链路的成本是它们之间的欧几里德距离的平方,即 \((x_i-x_j)^2+(y_i-y_j)^2\)
请聪明的你构建一个所有奶牛都能交流的最低成本的通信网络。如果两头奶牛通过一条链接直接连接或者它们的信息可以沿着一条链接传播,那么认为他们可以通信。
注意 此问题时间限制为4秒
输入格式
第一行输入为 \(N\),接下来 \(N\) 行分别描述奶牛的位置 \((x,y)\) 均为整数
输出格式
请输出允许所有奶牛通信的网络的最低成本。请注意,此开销可能太大,无法放入 32 位整数中,并且可能需要使用 64 位整数(例如,C++中的“long long”)。
输入输出样例 #1
输入 #1
10
83 10
77 2
93 4
86 6
49 1
62 7
90 3
63 4
40 10
72 0
输出 #1
660
说明/提示
测试点 2~3 满足 \(N\le1000\)。
测试点 4~15 没有特殊限制。
解法&&个人感想
其实就是抖机灵题目 完全图你看到$ n \le 10^5 $肯定用Kruscal和Prim都得爆
我们看到y<=10 说明y对距离的贡献是非常小的
那么 只需将点的x排序 然后在一定范围内建边就可以
最后跑Kruscal 完事
下面看代码:
#include<bits/stdc++.h>
#define int long long
#define maxn 100005
using namespace std;
struct dot{
int x,y;
};
dot k[maxn];
int n;
struct Edge{
int from,to,w;
};
Edge edge[26*maxn];
int fa[maxn];
int ans,cnt;
bool cmp_1(dot a,dot b){
return a.x<b.x;
}
bool cmp_2(Edge x,Edge y){
return x.w<y.w;
}
int get(int x){
if(fa[x]==x) return x;
return fa[x]=get(fa[x]);
}
void merge(int x,int y){
fa[x]=y;
return ;
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>k[i].x>>k[i].y;
}
for(int i=1;i<=n;i++) fa[i]=i;
sort(k+1,k+1+n,cmp_1);
for(int i=1;i<=n;i++){
for(int j=i;j<=n&&j<=i+25;j++){
edge[++cnt].from=i;
edge[cnt].to=j;
edge[cnt].w=(k[i].x-k[j].x)*(k[i].x-k[j].x)+(k[i].y-k[j].y)*(k[i].y-k[j].y);
}
}
sort(edge+1,edge+1+cnt,cmp_2);
for(int i=1;i<=cnt;i++){
int x=get(edge[i].from),y=get(edge[i].to);
if(x==y) continue;
ans+=edge[i].w;
merge(x,y);
}
cout<<ans;
system("pause");
return 0;
}
今天更新了博客播放器(Aplayer内置)的曲库:
目前曲目:
1.不可思议的病例 -《青春猪头少年不会梦见兔女郎学姐》ED
2.雪融 -《我的青春恋爱物语果然有问题》OP
3.Hello,Alone - 《我的青春恋爱物语果然有问题》ED
4.春拟 - 《我的青春恋爱物语果然有问题。续》OP
5.Everyday World - 《我的青春恋爱物语果然有问题。续》ED
6.萌芽之雨 - 《我的青春恋爱物语果然有问题。完》OP
7.钻石的纯度 - 《我的青春恋爱物语果然有问题。完》ED
世界名画镇楼


浙公网安备 33010602011771号