题意:给定N个点的坐标,这N个点之间需要进行通讯。通讯方式可以采用卫星通信或无线通信,若两点之间采用为卫星通信,则两点之间的距离无限制,若采用无线通讯,则两点之间的距离不能大于某个值D。
现有s台卫星通信设备可以分配给这N个点,其余的点之间必须使用无线通信。要让这N个点中所有的点都能相互通信,则合理分配s台卫星通信设备,可以使得采用无线通信的那些点之间的距离D达到一个最小值,求该最小值。
先求出最小生成树,则最大的s-1条边可以用卫星通信,则从大到小第s条边即为所求
G++不能用lf输出double,改为f。。。。。。
链接:poj 2349
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <vector>
#include <sstream>
#define ll long long
using namespace std;
const int maxn = 1000 + 10;
const int maxm = 1000000;
const int inf = 0x3f3f3f3f;
int fa[maxn];
int rnk[maxn];
double num[maxn];
int n, m;
struct node {
int a, b;
double c;
friend bool operator < (node x, node y) {
return x.c < y.c;
}
}q[maxm];
void init() {
for(int i = 0; i <= n; i++) {
fa[i] = i;
rnk[i] = 0;
}
}
int getf(int x) {
if(x != fa[x]) {
fa[x] = getf(fa[x]);
}
return fa[x];
}
void unions(int x, int y) {
x = getf(x);
y = getf(y);
if(x == y) return;
if(rnk[x] < rnk[y]) {
fa[x] = y;
}
else {
fa[y] = x;
if(rnk[x] == rnk[y]) rnk[x]++;
}
}
bool same(int x, int y) {
return getf(x) == getf(y);
}
void kruskal() {
init();
sort(q + 1, q + 1 + m);
int ans = 0;
int nedge = 0;
for(int i = 1; i <= m && nedge != n - 1; i++) {
if(getf(q[i].a) != getf(q[i].b)) {
unions(q[i].a, q[i].b);
num[nedge] = q[i].c;
nedge++;
}
}
//if(nedge < n - 1) ans = -1;
//return ans;
}
double x[maxn], y[maxn];
double dis(int i, int j) {
return sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
}
int main()
{
int T, kcase = 0;
cin >> T;
while(T--) {
int k;
scanf("%d %d", &k, &n);
m = 0;
for(int i = 1; i <= n; i++) {
scanf("%lf %lf", &x[i], &y[i]);
for(int j = 1; j < i; j++) {
double res = dis(i, j);
q[++m].a = i;
q[m].b = j;
q[m].c = res;
}
}
kruskal();
sort(num, num + n - 1);
printf("%.2lf\n", num[n - k - 1]);
}
return 0;
}