题意:第一行:测试数据数目:t
第二行:卫星数:s和哨所数e;
接下来e行:每个哨所的坐标;
有卫星的两个哨所可以随意通信,剩下的就等同于求最小生成树的最大边权
方法:把边权最大的s条边去掉,用最小生成树求剩下边的最边权;
贴代码:
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
double inf=999999999.00;
const int maxn=100010;
struct node{
double x,y;
}a[maxn];
double e[510][510],dis[maxn],zd[maxn];
int p[maxn];
double genghao(double x1,double y1,double x2,double y2){
return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
int main(){
int i,n,m,k,j,o,sum,end;
double ans;
scanf("%d",&o);
while(o--){
sum=0;
ans=0.00;
scanf("%d%d",&m,&n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++){
if(i==j)e[i][j]=0;
else e[i][j]=inf;
p[i]=0;
}
for(i=1;i<=n;i++){
scanf("%lf%lf",&a[i].x,&a[i].y);
}
for(i=1;i<=n-1;i++)
for(j=i+1;j<=n;j++){
e[i][j]=e[j][i]=genghao(a[i].x,a[i].y,a[j].x,a[j].y);
}
for(i=1;i<=n;i++)
dis[i]=e[1][i];
dis[1]=0;
p[1]=1;
int cnt=1;
while(cnt<n){
double min=inf;
for(i=1;i<=n;i++){
if(!p[i]&&dis[i]<min){
min=dis[i];
end=i;
}
}
zd[++sum]=dis[end];
p[end]=1;
cnt++;
for(j=1;j<=n;j++){
if(!p[j]&&dis[j]>e[end][j])
dis[j]=e[end][j];
}
}
sort(zd+1,zd+sum+1);
printf("%.2f\n",zd[n-m]);
}
return 0;
}