题目描述
国防部(DND)希望通过无线网络连接几个北部前哨站。
在建立网络时将使用两种不同的通信技术:每个前哨站都有一个无线电收发器,一些前哨站还有一个通信卫星。
任意两个拥有通信卫星的前哨站不论它们的位置如何,都可以通过卫星进行通信。
而如果利用无线电进行通信,则需要两个前哨站的距离不能超过D方可进行通信。
而D的大小取决于收发器的功率,收发器的功率越大,D也就越大,但是需要的成本也就越高。
出于采购和维护的考虑,所有的前哨站都采用相同的收发器,也就是说所有前哨站的无线电通信距离D都是相同的。
你需要确定在保证任意两个前哨站之间都能进行通信(直接或间接)的情况下,D的最小值是多少。
输入格式
第一行包含整数N,表示共有N组测试数据。
每组数据的第一行包含两个整数S和P,其中S为卫星个数,P为前哨站个数。
接下来P行每行包含两个整数x和y,分别表示一个前哨站的横纵坐标。
输出格式
输出一个实数,表示D的最小值,结果保留两位小数。
样例
样例输入
1
2 4
0 100
0 300
0 600
150 750
样例输出
212.13
题解
比较版的题,先邻接矩阵预处理两点见距离,再用Kruskal算法跑最小生成树。因为卫星可以不考虑距离,所以答案为最小生成树第S+1长的边。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int M=1e6+5;
struct edge{
int u,v;
double w;
}G[M];
struct node{
int x,y;
}a[M];
int n,fa[M],cnt,T,p;
double P(int l,int r,int ll,int rr){
return sqrt((ll-l)*(ll-l)+(rr-r)*(rr-r));
}
void Makeset(){
for(int i=1;i<=n;i++){
fa[i]=i;
}
}
int Findset(int x){
if(fa[x]!=x){
fa[x]=Findset(fa[x]);
}
return fa[x];
}
void Unionset(int u,int v){
fa[v]=u;
}
bool cmp(edge e1,edge e2){return e1.w<e2.w;}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d %d",&p,&n);
Makeset();
cnt=0;
for(int i=1;i<=n;i++){
scanf("%d %d",&a[i].x,&a[i].y);
for(int j=1;j<i;j++){
G[++cnt].u=i;G[cnt].v=j;G[cnt].w=P(a[i].x,a[i].y,a[j].x,a[j].y);
G[++cnt].v=i;G[cnt].u=j;G[cnt].w=G[cnt-1].w;
}
}
sort(G+1,G+cnt+1,cmp);
int tot=1,_tot=1;double ans=0;
while(_tot<=cnt&&tot<=n-p){
int r1=Findset(G[_tot].u);
int r2=Findset(G[_tot].v);
if(r1!=r2){
ans=max(ans,G[_tot].w);
Unionset(r1,r2);
tot++;
}
_tot++;
}
printf("%.2lf\n",ans);
}
return 0;
}
AC!
本文介绍了如何使用Kruskal算法解决一个军事通信网络问题。在连接多个北部前哨站时,需要确定最小的通信距离D,使得所有前哨站间都能直接或间接通信。问题涉及到卫星通信和无线电通信,其中卫星通信不受距离限制,无线电通信受限于收发器的功率。通过建立邻接矩阵并应用Kruskal算法求解最小生成树,找到第S+1长的边的长度作为答案。
359

被折叠的 条评论
为什么被折叠?



