1487:【例 2】北极通讯网络

题目描述

北极的某区域共有 n 座村庄,每座村庄的坐标用一对整数 (x,y) 表示。为了加强联系,决定在村庄之间建立通讯网络。通讯工具可以是无线电收发机,也可以是卫星设备。所有的村庄都可以拥有一部无线电收发机, 且所有的无线电收发机型号相同。但卫星设备数量有限,只能给一部分村庄配备卫星设备。

不同型号的无线电收发机有一个不同的参数 d,两座村庄之间的距离如果不超过 d 就可以用该型号的无线电收发机直接通讯,d 值越大的型号价格越贵。拥有卫星设备的两座村庄无论相距多远都可以直接通讯。

现在有 k 台卫星设备,请你编一个程序,计算出应该如何分配这 k 台卫星设备,才能使所拥有的无线电收发机的 d 值最小,并保证每两座村庄之间都可以直接或间接地通讯。

输入

第一行为由空格隔开的两个整数 n,k;
第 2∼n+1 行,每行两个整数,第 i 行的 xi,yi​ 表示第 i 座村庄的坐标 (xi,yi)。

输出

一个实数,表示最小的 d 值,结果保留 2 位小数。

输入样例

3 2
10 10
10 0
30 0

输出样例

10.00

思路

题目的意思是求最小生成树的第k大的边的长度

#include<bits/stdc++.h>
#define read() freopen("input.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
using namespace std;
const int maxn = 1e6+10;
int pre[505];
vector<double>v;
struct dot{
	int start,end;
	double len;
}city[maxn];
struct poi{
	int x,y;
}s1[505];
double getdis(poi a,poi b){
	return sqrt(pow(a.x-b.x,2)+pow(a.y-b.y,2));
}
int find(int x){
	return x==pre[x]?x:pre[x]=find(pre[x]);
}
bool cmp(dot a,dot b){
	return a.len<b.len;
}
int main(){
	read();write();
	int k,n,cnt=0;
	cin>>n>>k;
	for( int i=1; i<=n; i++ ) pre[i]=i;
	for( int i=0; i<n; i++ ) cin>>s1[i].x>>s1[i].y;
	for( int i=0; i<n; i++ ){
		for( int j=i+1; j<n; j++ ){
			city[cnt].start=i;city[cnt].end=j;
			city[cnt++].len=getdis(s1[i],s1[j]);
		}
	}
	sort(city,city+cnt,cmp);
	for( int i=0; i<cnt; i++ ){
		int a=find(city[i].start);
		int b=find(city[i].end);
		if(a!=b){
			pre[a]=b;
			v.push_back(city[i].len);
		}
	}
	sort(v.begin(),v.end(),greater<double>());
	printf("%.2f",v[k-1]);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值