题目链接
Solution
\(Kruskal\) .
一直维护生成树,同时记录一下联通块数量.
如果联通块数量为 \(s+1\),那么直接结束.
最后输出答案即可.
Code
#include<bits/stdc++.h>
#define db double
using namespace std;
const int maxn=20008;
struct sj{int fr,to;db w;}a[maxn];
bool cmp(sj x,sj y){return x.w<y.w;}
db x[maxn],y[maxn],ans;
int fa[maxn],n,p,num,cnt;
int find(int x)
{if(x==fa[x])return x;else return fa[x]=find(fa[x]);}
void join(int x,int y)
{x=find(x); y=find(y);if(x!=y)fa[x]=y;}
int main()
{
cin>>p>>n; num=n;
for(int i=1;i<=n;i++)
scanf("%lf%lf",&x[i],&y[i]),fa[i]=i;
for(int i=1;i<=n;i++)
for(int j=2;j<=n;j++)
{
a[++cnt].fr=i;
a[cnt].to=j;
a[cnt].w=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[j]-y[i])*(y[j]-y[i]));
}
sort(a+1,a+cnt+1,cmp);
for(int i=1;i<=cnt;i++)
{
if(num==p)break;
if(find(a[i].fr)!=find(a[i].to))
join(a[i].fr,a[i].to),ans=max(ans,a[i].w),num--;
}
printf("%.2lf\n",ans);
}