【输入样例】
3 2
10 10
10 0
30 0
【输出样例】
10.00
解析:
题意为在最小生成树中,选择一些点,删去这些点之间的这些边,问剩余最大的边是多长。
Kruskal算法,因为是从小到大遍历的边,所以记录当前连通块的个数,当连通块小于等于k时,此时相当于在最小生成树中删去了一些边,而且都是较大的边。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=510;
int n,k,vis[N],p[N];
pair<int,int>v[N];
struct node{
int dis,a,b;
bool operator<(const node& t)const{
return dis<t.dis;
}
};
vector<node>e;
int find(int x){
if(x!=p[x]) p[x]=find(p[x]);
return p[x];
}
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d%d",&v[i].first,&v[i].second);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
int dis=pow(v[i].first-v[j].first,2)+pow(v[i].second-v[j].second,2);
e.push_back({dis,i,j});
}
sort(e.begin(),e.end());
for(int i=1;i<=n;i++) p[i]=i;
int res=0,cnt=n;
for(int i=0;i<e.size();i++){
if(cnt<=k) break;
int x=find(e[i].a),y=find(e[i].b),w=e[i].dis;
if(x!=y){
p[x]=y;
cnt--;
res=w;
}
}
printf("%.2lf",sqrt(res));
return 0;
}