问题描述
国防部计划用无线网络连接若干个边防哨所。2种不同的通讯技术用来搭建无线网络;每个边防哨所都要配备无线电收发器;有一些哨所还可以增配卫星电话。
任意两个配备了一条卫星电话线路的哨所(两边都拥有卫星电话)均可以通话,无论他们相距多远。而只通过无线电收发器通话的哨所之间的距离不能超过D,这是受收发器的功率限制。收发器的功率越高,通话距离D会更远,但同时价格也会更贵。
收发器需要统一购买和安装,所以全部哨所只能选择安装一种型号的收发器。换句话说,每一对哨所之间的通话距离都是同一个D。
你的任务是确定收发器必须的最小通话距离D,使得每一对哨所之间至少有一条通话路径(直接的或者间接的)。
输入格式
第1行:2个整数S(1≤S≤100)和P(S<P≤500),S表示可安装的卫星电话的哨所数,P表示边防哨所的数量。
接下里P行,每行描述一个哨所的平面坐标(x,y),以km为单位,整数,0≤x,y≤10000。
输出格式
第1行:1个实数D,表示无线电收发器的最小传输距离。精确到小数点后两位。
样例
输入
2 4
0 100
0 300
0 600
150 750
输出
212.13
数据范围
- 对于20%的数据 P=2,S=1
- 对于另外20%的数据 P=4,S=2
- 对于100%的数据 1≤S≤100,S<P≤500
解决方案
思路
Kruskal
代码
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
struct Node {
int x, y;
double w;
};
const int N = 505;
int s, p;
int x[N], y[N];
vector<pair<int, int>> g[N]; //下标:连接点 first:被连接的点 second:距离
vector<Node> e;
int fa[N];
bool cmp(const Node &x, const Node &y) {
return x.w < y.w;
}
void init() {
for (int i = 0; i < N; ++i) {
fa[i] = i;
}
}
int find(int x) {
if (fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
void join(int x, int y) {
int a = find(x);
int b = find(y);
fa[a] = b;
}
int main() {
cin >> s >> p;
for (int i = 1; i <= p; ++i) {
cin >> x[i] >> y[i];
}
for (int i = 1; i <= p; i++) {
for (int j = i + 1; j <= p; j++) {
double w = sqrt((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]));
g[i].push_back({j, w});
g[j].push_back({i, w});
Node node;
node.x = i;
node.y = j;
node.w = w;
e.push_back(node);
}
}
sort(e.begin(), e.end(), cmp);
init();
priority_queue<double> q;
for (int i = 0; i < e.size(); ++i) {
Node node = e[i];
int a = find(node.x);
int b = find(node.y);
if (a != b) {
join(a, b);
q.push(node.w);
}
}
for (int i = 0; i < s - 1; ++i) {
q.pop();
}
printf("%.2f", q.top());
return 0;
}