#include<bits/stdc++.h>
using namespace std;
int nodesnum;
int satellite;
struct node {
int x, y;
};
struct edge {
int x, y;
double value;
bool operator<(const edge &temp) const {
return value < temp.value;
}
};
vector<node> nodes;
vector<edge> edges;
int parent[510];
bool satellite_or_not[510];
bool cmp(edge x, edge y) {
return x.value < y.value;
}
double dist(int x, int y) {
return sqrt(pow(nodes[x].x - nodes[y].x, 2) + pow(nodes[x].y - nodes[y].y, 2));
}
int fin(int x) {
if (x != parent[x]) parent[x] = fin(parent[x]);
return parent[x];
}
priority_queue<edge> pq;
double ans = 0;
int cnt = 0;
void kruskal() {
sort(edges.begin(), edges.end(), cmp);
for (int i = 0; i < edges.size(); ++i) {
int rootx = fin(edges[i].x), rooty = fin(edges[i].y);
if (rootx != rooty) {
cnt++;
parent[rootx] = rooty;
ans = max(ans, edges[i].value);
pq.push(edges[i]);
if (cnt == nodesnum - 1) return;
}
}
}
int main() {
cin >> satellite >> nodesnum;
nodes.resize(nodesnum + 1);
for (int i = 1; i <= nodesnum; ++i) {
cin >> nodes[i].x >> nodes[i].y;
parent[i] = i;
}
for (int i = 1; i <= nodesnum; ++i) {
for (int j = i + 1; j <= nodesnum; ++j) {
edges.push_back({i, j, dist(i, j)});
}
}
kruskal();
if (satellite < 2) printf("%.2f", ans);
else {
satellite -= 2;
//cout<<pq.top().value<<endl;
satellite_or_not[pq.top().x] = 1, satellite_or_not[pq.top().y] = 1;
pq.pop();
ans = pq.top().value;
while (satellite > 0) {
int x = pq.top().x, y = pq.top().y;
if (satellite_or_not[x] || satellite_or_not[y]) {
satellite_or_not[x] = 1, satellite_or_not[y] = 1;
pq.pop();
ans = pq.top().value;
satellite--;
} else {
if (satellite >= 2) {
int x = pq.top().x, y = pq.top().y;
satellite_or_not[x] = 1, satellite_or_not[y] = 1;
pq.pop();
ans = pq.top().value;
satellite -= 2;
} else {
break;
}
}
}
printf("%.2f", ans);
}
}
先求出mst 然后判断卫星电话数量 只有大于等于二才能删边 满足条件删最大边 此后每次最大边两个端点可能有一个是已经有卫星电话了 可能只需要一个卫星电话就行 然后一点一点判断。。。60/100pts 谢谢各位帮忙。。。