这题就是用最少的路径,使得图有S个连通分量。再求这些路径中的最大值。
用Kruskal算法,在刚好有S个连通分量时终止运算就行了。
double max(double a,double b) {return a>b?a:b;}
//outpost
struct outpost{
int x,y;
outpost():x(0),y(0){}
void init(int x,int y){
this->x=x;this->y=y;
}
int operator*(const outpost&b)const{
return (x-b.x)*(x-b.x)+(y-b.y)*(y-b.y);
}
}I[500];
int In;
//边
struct edge{
int from,to;
double value;
void init(int from,int to,double value){
this->from=from;this->to=to;this->value=value;
}
bool operator <(const edge&b)const{
return value<b.value;
}
}edges[125000];
int En;
//并查
struct node{
int parent;
void init(int i){
parent=i;
}
}nodes[500];
int find(int x){
int r=x;
while(r!=nodes[r].parent){
r=nodes[r].parent;
}
return nodes[x].parent=r;
}
int main(void)
{
int T;cin>>T;
while(T--){
int S,C,x,y;
scanf("%d%d",&S,&C);In=0;
//存outpost位置
for(int i=0;i<C;i++){
scanf("%d%d",&x,&y);
I[In++].init(x,y);
}
//建边
En=0;
for(int i=0;i<C;i++){
for(int j=i+1;j<C;j++){
int D2=I[i]*I[j];
edges[En++].init(i,j,sqrt((double)D2));
}
}
//排序
sort(edges,edges+En);
double ANS=0;
//计算
for(int i=0;i<C;i++){//并查集初始化
nodes[i].init(i);
}
int NNN=C;//NNN代表有几个连通分量
for(int i=0;i<En;i++){
if(NNN==S) break;//恰好有S个连通分量时结束
static int a,b;
a=find(edges[i].from),b=find(edges[i].to);
if(a==b) continue;
NNN--;
nodes[a].parent=b;
ANS=max(ANS,edges[i].value);
}
printf("%.2f\n",ANS);
}
return 0;
}