一开始总想着二分答案,发现不会贪。。
其实就是选出最小生成树的前n-k条边之后下一条有用的边的长度,排序之后上kruskal就行了。。
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#define N 1005
using namespace std;
struct edge{
int s,e;
double q;
edge(){}
edge(int s,int e,double q):s(s),e(e),q(q){}
}ed[N*N];
int n,k,i,j,ne=0,s,e,fs,fe,now,fa[N],x[N],y[N];
double q;
double sqr(int a){return (double)a*a;}
double dis(int i,int j){return sqrt(sqr(x[i]-x[j])+sqr(y[i]-y[j]));}
bool cmp(edge a,edge b){return a.q<b.q;}
int getfa(int x){return x==fa[x]?x:fa[x]=getfa(fa[x]);}
int main()
{
scanf("%d%d",&n,&k);
for (i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]),fa[i]=i;
for (i=1;i<=n;i++)
for (j=i+1;j<=n;j++)
ed[++ne]=edge(i,j,dis(i,j));
sort(ed+1,ed+1+ne,cmp);
now=n;
for (i=1;i<=ne;i++)
{
s=ed[i].s;e=ed[i].e;q=ed[i].q;
fs=getfa(s);fe=getfa(e);
if (now==k&&fs!=fe) {printf("%.2lf",ed[i].q);return 0;}
if (fs!=fe) fa[fs]=fe,now--;
}
}