1、刚开始看这道题还以为是最短路,因为没有注意到两个地点用的是一个仪器。
2、其实就是求最小生成树的第s-n小边。
3、数组开小了,RE了两次。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
struct point{
int x,y;
}a[510];
struct edge{
int u,v;
double w;
}e[250010];
int p[510],r[250010],s,n,m;
int cmp(const int i,const int j){return e[i].w<e[j].w;}
int find(int x){return p[x]==x?x:p[x]=find(p[x]);}
double Kruskal(){
for(int i=0;i<n;i++) p[i]=i;
for(int i=0;i<m;i++) r[i]=i;
sort(r,r+m,cmp);
int cnt=0;
for(int i=0;i<m;i++){
int temp=r[i];int x=find(e[temp].u);int y=find(e[temp].v);
if(x!=y){
cnt++;
if(cnt==n-s) return e[temp].w;
p[x]=y;
}
}
return 0;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&s,&n);
for(int i=0;i<n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
m=0;
for(int i=0;i<n-1;i++)
for(int j=i+1;j<n;j++){
e[m].u=i;
e[m].v=j;
e[m].w=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
m++;
}
printf("%.2lf\n",Kruskal());
}
return 0;
}