这道题其实就是无线通讯网的双倍经验啦,只是在输出的时候不同罢了。还是一样的(kruskal)算法,但是在求的时候,应该在(now=n-k+1)的时候结束。本来到(n-k)就行了的,但是由于(n-k+1)这条边是在应该部落里面的,不能算,所以要找到第一个不在一个部落里面的边。
代码:
#include <bits/stdc++.h>
using namespace std;
struct node{
int l , r;
double w;
};
int n , k , tot , now;
int fa[1010];
double ans;
double dx[1010] , dy[1010];
node e[100000010];
double work(int i , int j){
return sqrt((dx[i] - dx[j]) * (dx[i] - dx[j]) + (dy[i] - dy[j]) * (dy[i] - dy[j]));
}
bool cmp(node x , node y){
return x.w < y.w;
}
int find(int x){
if(x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
int main(){
cin >> n >> k;
for(int i = 1; i <= n; i++) cin >> dx[i] >> dy[i];
for(int i = 1; i <= n; i++)
for(int j = 1; j < i; j++){
tot++;
e[tot].l = i;
e[tot].r = j;
e[tot].w = work(i , j);
}
sort(e + 1 , e + tot + 1 , cmp);
for(int i = 1; i <= n; i++) fa[i] = i;
for(int i = 1; i <= tot; i++){
if(now == n - k + 1) break;
int x = find(e[i].l) , y = find(e[i].r);
if(x == y) continue;
now++;
ans = e[i].w;
fa[x] = y;
}
printf("%.2f" , ans);
return 0;
}