二分距离最小值。两个点的距离小于这个值,就一定要在同一个部落中。并查集判断一下就行了。
#include<cstdio>
#include<algorithm>
#define sqr(x) ((x)*(x))
using namespace std;
typedef long long LL;
const int maxn=1005;
int n,m,a[maxn],b[maxn],fa[maxn];
double mid;
int getfa(int x){ return fa[x]==x?x:fa[x]=getfa(fa[x]); }
void merge(int x,int y){ x=getfa(x); y=getfa(y); if(x!=y) fa[x]=y; }
bool check(){
for(int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++) if(sqr(a[i]-a[j])+sqr(b[i]-b[j])<mid*mid) merge(i,j);
int res=0;
for(int i=1;i<=n;i++) if(getfa(i)==i) res++;
return res>=m;
}
int main(){
freopen("bzoj1821.in","r",stdin);
freopen("bzoj1821.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]);
double L=0.01,R=1e12;
while(R-L>=0.001){
mid=(L+R)/2;
if(check()) L=mid; else R=mid;
}
printf("%.2lf\n",L);
return 0;
}