洛谷题单<最小生成树> 无线通讯网
水题 直接kruskal 加边数 == p - s 返回边长即可
代码如下
#include<bits/stdc++.h>
using namespace std;
const int N = 510;
int s, p;
struct edge{
int a, b;
double c;
bool operator<(const edge & w)const{
return c < w.c;
}
}edges[N * N];//完全图
struct node{
int x, y;
}node[N];
int pp[N];//并查集
int find(int x){
if(pp[x] == x) return x;
else return pp[x] = find(pp[x]);
}
double kruskal(int n){
for(int i = 1; i <= p; i++) pp[i] = i;
int res = 0;
for(int i = 0; i < n; i ++){
int a = edges[i].a, b = edges[i].b;
double z = edges[i].c;
int x = find(a), y = find(b);
if(x != y){
res ++;
if(res == p - s) return z; //退出循环
pp[x] = y;
}
}
}
int main(){
cin >> s >> p;
for(int i = 1; i <= p; i++){
int a, b;
scanf("%d%d", &a, &b);
node[i] = {a, b};
}
int cnt = 0;
for(int i = 1; i <= p; i++){
for(int j = i + 1; j <= p; j++){
double z = sqrt((node[i].x-node[j].x)*(node[i].x-node[j].x)+(node[i].y-node[j].y)*(node[i].y-node[j].y));
edges[cnt++] = {i, j, z};
}
}
sort(edges, edges + cnt);
double D = kruskal(cnt);
printf("%.2f", D);
}
