我的思路是二分答案 + 生成树,判断是否边界被生成树连通
#include <bits/stdc++.h>
#define re register int
using namespace std;
const int N = 1e3 + 10, inf = 1e8 + 10;
const double eps = 1e-6;
struct node
{
int x, y;
}a[N];
struct edge
{
int x, y;
double len;
}e[N * N];
int top, fa[N];
int n, m;
bool cmp(edge i, edge j) { return i.len < j.len; }
inline int find(int x)
{
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
inline double dis(node i, node j)
{
return sqrt((i.x - j.x) * (i.x - j.x) + (i.y - j.y) * (i.y - j.y));
}
inline void build()
{
for (re i = 1; i <= m; i ++)
for (re j = i + 1; j <= m; j ++)
e[++ top] = {i, j, dis(a[i], a[j])};
sort(e + 1, e + top + 1, cmp);
}
inline bool check(double mid)
{
bool l = false, r = false;
for (re i = 1; i <= m; i ++) fa[i] = i;
for (re i = 1; i <= top; i ++)
{
int x = e[i].x, y = e[i].y;
double len = e[i].len;
if (find(x) != find(y) && mid * 2 >= len)
{
fa[find(x)] = find(y);
if (x - mid <= 0 || y - mid <= 0) l = true;
if (x + mid >= n || y + mid >= n) r = true;
if (l && r) return true;
}
}
return false;
}
int main()
{
scanf("%d %d", &n, &m);
for (re i = 1; i <= m; i ++) scanf("%d %d", &a[i].x, &a[i].y);
build();
double l = 0, r = inf;
while (l + eps < r)
{
double mid = (l + r) / 2;
if (check(mid)) r = mid, printf("%.8lf\n", mid);
else l = mid;
}
printf("%.2lf\n", r);
return 0;
}