用 Kruskal 的话,并查集初始化的时候一定不要忘记把 0 号点和 n+1 号点也初始化。如果不这样的话,会爆掉!
#include <bits/stdc++.h>
using namespace std;
using db = double;
const int N = 805;
int n, m, idx;
int x[N], y[N], fa[N];
struct Edge{
int u, v; db w;
bool operator <(Edge other){
return w < other.w;
}
}e[N * N];
void init(){
// 如果写成 for(int i = 1; i <= n; i++) fa[i] = i; 就会错
for(int i = 0; i <= n + 1; i++)
fa[i] = i;
}
inline db getdis(int a, int b){
db dx = fabs((db)x[a] - x[b]), dy = fabs((db)y[a] - y[b]);
return sqrt(dx * dx + dy * dy);
}
inline int find(int x){
return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
}
db kruskal(){
sort(e + 1, e + 1 + idx);
db ans = -1;
for(int i = 1; i <= idx; i++){
int a = e[i].u, b = e[i].v;
if(find(a) != find(b)){
fa[find(a)] = find(b);
ans = max(ans, e[i].w);
}
if(find(0) == find(n + 1))
return ans;
}
}
int main(){
scanf("%d%d", &n, &m);
init();
for(int i = 1; i <= n; i++)
scanf("%d%d", &x[i], &y[i]);
for(int i = 1; i < n; i++)
for(int j = i + 1; j <= n; j++)
e[++idx] = (Edge){i, j, getdis(i, j) / 2};
for(int i = 1; i <= n; i++){
e[++idx] = (Edge){i, 0, x[i]};
e[++idx] = (Edge){i, n + 1, n - x[i]};
}
printf("%.2lf", kruskal());
return 0;
}