题解 : https://xiaoxiaoh.blog.csdn.net/article/details/104223633
一、内容
The Department of National Defence (DND) wishes to connect several northern outposts by a wireless network. Two different communication technologies are to be used in establishing the network: every outpost will have a radio transceiver and some outposts will in addition have a satellite channel.
Any two outposts with a satellite channel can communicate via the satellite, regardless of their location. Otherwise, two outposts can communicate by radio only if the distance between them does not exceed D, which depends of the power of the transceivers. Higher power yields higher D but costs more. Due to purchasing and maintenance considerations, the transceivers at the outposts must be identical; that is, the value of D is the same for every pair of outposts.
Your job is to determine the minimum D required for the transceivers. There must be at least one communication path (direct or indirect) between every pair of outposts.
Input
The first line of input contains N, the number of test cases. The first line of each test case contains 1 <= S <= 100, the number of satellite channels, and S < P <= 500, the number of outposts. P lines follow, giving the (x,y) coordinates of each outpost in km (coordinates are integers between 0 and 10,000).
Output
For each case, output should consist of a single line giving the minimum D required to connect the network. Output should be specified to 2 decimal points.
Sample Input
1
2 4
0 100
0 300
0 600
150 750
Sample Output
212.13
二、思路
- 有k个点可以通过卫星相连,就不用花费什么代价,那么可以考虑边最大的时候才使用卫星相连。
- k个台卫星设备可以让k个连通块连通,那么我们通过kruskal不停的减少连通块,当连通块减少到k时候。就让剩下的都用卫星连接即可。 之前最大的边就是答案。
- 例如当 k == 3的时候,若连通块还剩3个那么可以让3个连通块通过卫星相连。
- 因为我们用kruskal 求解的时候是按照最少权值边进行的,所以后面的边肯定是大于之前的。
三、代码
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 505, M = N * N / 2;
struct Node {
int x, y;
} pt[N];
struct E {
int u, v;
double w;
bool operator < (const E&o) const {
return w < o.w;
}
} e[M];
int n, m, k, p[N];
int find(int x) {
return p[x] == x ? x : (p[x] = find(p[x]));
}
double getD(int i, int j) {
double x = pt[i].x - pt[j].x;
double y = pt[i].y - pt[j].y;
return sqrt(x*x + y*y);
}
int main() {
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) p[i] = i;
for (int i = 1; i <= n; i++) scanf("%d%d", &pt[i].x, &pt[i].y);
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
e[++m].u = i; e[m].v = j; e[m].w = getD(i, j);
}
}
sort(e + 1, e + 1 + m);
double ans = 0; int cnt = n; //最开始有n个连通快
//kruskal 求出还剩k个联通快的时候停止
for (int i = 1; i <= m; i++) {
if (cnt <= k) break; //代表连通快个数小于k 剩下的可以全部用卫星连接
int fu = find(e[i].u), fv = find(e[i].v);
if (fu != fv) {
p[fu] = fv;
ans = e[i].w;
cnt--; //少了一个连通块
}
}
printf("%.2lf", ans);
return 0;
}
此题非你哪题啊