题解:先跑一遍最小生成树,然后再删除前k大的边,再输出最大的那条边。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
int n,k;
int a[100000],b[100000],f[100000];
struct s
{
int u,v;
double w;
}s1[10000000];
int getf(int u)
{
if(u==f[u])
return u;
else
{
f[u]=getf(f[u]);
return f[u];
}
}
int merge(int u,int v)
{
int t1=getf(u);
int t2=getf(v);
if(t1!=t2)
{
f[t2]=t1;
return 1;
}
return 0;
}
bool cmp(s x,s y)
{
return x.w<y.w;
}
int main()
{
scanf("%d%d",&n,&k);
int i,j;
for(i=0;i<n;i++)
scanf("%d%d",&a[i],&b[i]);
int g=0;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
{
s1[g].u=i;
s1[g].v=j;
s1[g++].w=sqrt((a[j]-a[i])*(a[j]-a[i])+(b[j]-b[i])*(b[j]-b[i]));
}
for(i=0;i<=n;i++)
f[i]=i;
sort(s1,s1+g,cmp);
double sum=0;
int q=0;
int r=0;
for(i=0;i<g;i++)
{
if(merge(s1[i].u,s1[i].v))
{
r++;
sum=s1[i].w;
}
if(r==n-k)
break;
}
printf("%.2lf",sum);
//先跑一遍最小生成树,然后再删除前k大的边,再输出最大的那条边。
}