前言
这也可以歪成这个hh
二分答案待补
传送门 :
思路
如果这个题,每个点看作一个部落的话 , 我们贪心的根据边排序, 将最大的边的部
部落算成一个集合,那么我们就可以跑一遍 k r u s k a l kruskal kruskal算法,那么这题的答案就是求第
n − k + 1 n-k+1 n−k+1条边,总之抽象有点喜感,
CODE
const int N = 1e6+10;
int p[N];
int wx[N],wy[N];
int idx ;
int n,m,k;
struct node
{
int a,b;
double c;
bool operator <(const node & w){
return c < w.c;
}
}e[N];
int find(int x)
{
if(x!=p[x])return p[x] = find(p[x]);
return p[x];
}
double cal(int x,int y)
{
return sqrt(
(wx[x] - wx[y]) *(wx[x] - wx[y]) +
(wy[x] - wy[y]) *(wy[x] - wy[y])
);
}
void init()
{
for(int i=1;i<=n;i++)
p[i] = i ;
}
void kruskal()
{
int cnt = 0 ;
for(int i=1;i<=idx;i++)
{
// cout<< cnt<<" "<<n-k<<endl;
int a = e[i].a,b = e[i].b;
int fa = find(a) ,fb = find(b);
if(fa !=fb)
{
++cnt;
p[fa] = fb;
}
if(cnt == n-k+1)
{
printf("%.2lf",e[i].c);
return;
}
}
}
void solve()
{
cin>>n>>k;
init();
for(int i=1;i<=n;i++)
cin>>wx[i]>>wy[i];
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
e[++idx] = {i,j,cal(i,j)};
sort(e+1,e+1+idx);
kruskal();
}