#include using namespace std; typedef pair PII; #define x first #define y second const int N = 510; // 有向图 边数最多:n(n-1)/2 // 可以想象一下,每个点可以向其它n-1个点引边,共有n个点,就是n*(n-1)条边,因为一来一回算了两次,所以就是 n*(n-1)/2个,最大值设定 N*N/2 const int M = N * N / 2; int n, k; struct Edge { int a, b; double w; const bool operator<(const Edge &t) const { return w < t.w; } } e[M]; int el; // 每个村庄的坐标 PII q[M]; // 欧几里得距离 double get_dist(PII a, PII b) { int x = a.x - b.x, y = a.y - b.y; return sqrt(x * x + y * y); } // 并查集 int p[N]; int find(int x) { if (p[x] != x) p[x] = find(p[x]); return p[x]; } int main() { cin >> n >> k; // n座村庄,有k台卫星设备 for (int i = 0; i < n; i++) cin >> q[i].x >> q[i].y; // 村庄坐标 // 枚举所有点与点之间的边 for (int i = 0; i < n; i++) for (int j = i + 1; j < n; j++) // 记录单向边即可 e[el++] = {i, j, get_dist(q[i], q[j])}; // 边权由小到大排序 sort(e, e + el); // 并查集初始化 for (int i = 0; i < n; i++) p[i] = i; int cnt = n; // 剩余的连通块数量 double res = 0; // 原则:长的用卫星,短的用无线电收发机 // 合并完之后,正好剩下k个连通块,停止,每个连通块上安装卫星即可全面通讯 // 给原图的节点中n - k个节点生成一棵最小生成树 for (int i = 0; i < el; i++) { // 枚举每条边 if (cnt == k) break; // 剩余点数为k时停止, 在这k个点上建立卫星站 int a = find(e[i].a), b = find(e[i].b); if (a != b) { p[a] = b; cnt--; // 连通块数量-1 res = e[i].w; // 不停的记录参数d的上限 } } printf("%.2lf\n", res); return 0; }