正题
题目链接:https://www.luogu.org/problemnew/show/P4047
题目大意
将nnn个点分成kkk个部分,使得最近的两个部分的距离尽可能远。
解题思路
最小生成树连接到只剩下kkk个部分时停止就好了。
codecodecode
#include<cstdio>
#include<cmath>
#include<algorithm>
#define N 1010
#define p(c) ((c)*(c))
using namespace std;
int n,k,x[N],y[N],ans,father[N],cnt,now;
struct node{int x,y;double w;
}a[N*N];
double dist(int a,int b)
{return sqrt((double)p(x[a]-x[b])+p(y[a]-y[b]));
}
int find(int x)
{if(father[x]==x) return x;return find(father[x]);
}
void unionn(int x,int y)
{int fa=find(x),fb=find(y);if(fa>fb) father[fa]=fb;else father[fb]=fa;
}
bool cmp(node x,node y)
{return x.w<y.w;}
int main()
{scanf("%d%d",&n,&k);for(int i=1;i<=n;i++)scanf("%d%d",&x[i],&y[i]);for(int i=1;i<=n;i++)father[i]=i;k=n-k+1;for(int i=1;i<n;i++)for(int j=i+1;j<=n;j++)a[++cnt]=(node){i,j,dist(i,j)};sort(a+1,a+1+cnt,cmp);ans=2147483647;for(int i=1;i<=cnt;i++){if(find(a[i].x)!=find(a[i].y))k--,unionn(a[i].x,a[i].y);if(!k){printf("%.2lf",a[i].w);return 0;}}
}