传送门:北极通讯网络
思路:坐标化点存边,已知每0台卫星设备和1台没有区别最少需要两台才能消除一条最大边,在克鲁斯卡尔算法求最小生成树的过程中会产生多个连通块,连通块之间的边都是最大的那几条,也是要用卫星设备消除的那几条,k台设备一共可以消去k-1条边,所以只剩k个连通块时,最大的d就是已经在各个连通块中的最大的边
代码:
#include<iostream>
#include<cstring>
#include <cmath>
#include<algorithm>
#include <vector>
#include <stack>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int,int>PII;
const int N=510,M=N*N;
int cnt;
int n,m,k;
int f[N];
PII p[N];
struct edge
{
int a,b;
double c;
}edges[M];
bool cmp(edge a,edge b)
{
return a.c<b.c;
}
double get_dist(PII a,PII b)
{
int dx=a.x-b.x;
int dy=a.y-b.y;
return sqrt(dx*dx+dy*dy);
}
int get(int x)
{
if(f[x]==x)
return x;
return f[x]=get(f[x]);
}
int main()
{
cin>>n>>k;
int m=0;
int ans=0;
for(int i=1;i<=n;i++)
f[i]=i;
for(int i=1;i<=n;i++)
cin>>p[i].x>>p[i].y;
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
edges[++m]={i,j,get_dist(p[i],p[j])};
sort(edges+1,edges+m+1,cmp);
int cnt=n;
double res=0;
for(int i=1;i<=m;i++)
{
if(cnt<=k) break;
int a=get(edges[i].a),b=get(edges[i].b);
double w=edges[i].c;
if(a!=b)
{
f[a]=b;
cnt--;
res=w;
}
}
printf("%.2lf\n",res);
return 0;
}