每合并一次,部落数减一,最终合并到合法的数量。
若i时得到nk时,不能确定w[i+1]即为答案,因为可能u[i+1].fv[i+1].f,所以还需要再往下枚举判断。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1005;
int n,k,cnt,tot;
bool flag;
int f[N];
struct node{
int u,v;
}a[N];
struct Node{
int u,v;
double w;
}edge[N*N];
bool cmp(Node a,Node b){
return a.w<b.w;
}
int find(int x){
if(f[x]==x) return f[x];
return f[x]=find(f[x]);
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].u,&a[i].v);
}
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
edge[++cnt].u=i; edge[cnt].v=j; edge[cnt].w=sqrt((a[i].u-a[j].u)*(a[i].u-a[j].u)+(a[i].v-a[j].v)*(a[i].v-a[j].v));
}
sort(edge+1,edge+cnt+1,cmp);
for(int i=1;i<=cnt;i++){
int r1=find(edge[i].u);
int r2=find(edge[i].v);
if(r1==r2) continue;
f[r1]=r2;
n--;
if(n==k){
flag=1;
continue;
}
if(flag){
printf("%.2f",edge[i].w);//不一定下一个就是
break;
}
}
return 0;
}