题目链接:https://ac.nowcoder.com/acm/contest/303/F

       要求一个最小的r使得所有的塔连通,所以我们就去二分半径r,然后用bfs去判断图是否连通就好了。


AC代码:

#include <bits/stdc++.h>
#define maxn 505
#define ll long long
using namespace std;
int T;
int n;
ll x[maxn],y[maxn];
ll pre[maxn][maxn];
bool vis[maxn];
  
ll dist(ll x1,ll y1,ll x,ll y){
    double ans = sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y));
    return ceil(ans);
}
  
bool Check(ll r){
    memset(vis,false,sizeof(vis));
    queue<int> q;
    q.push(1);
    vis[1] = true;
    int ans = 0;
    while(!q.empty()){
        int u = q.front();
        q.pop();
        if(ans == n - 1)return true;
        for(int i=1;i<=n;i++){
            if(i == u) continue;
            if(vis[i] == false && pre[u][i] <= 2.0 * r){
                vis[i] = true;
                ans ++;
                q.push(i);
            }
        }
    }
    return false;
}
  
int main()
{
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%lld%lld",&x[i],&y[i]);
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                pre[i][j] = dist(x[i], y[i], x[j], y[j]);
                // Max = max(Max, pre[i][j]);
            }
        }
        ll l = 0, r = 2e18, mid;
        while(l < r){
            mid = (l + r) >> 1;
            if(Check(mid)){
                r = mid;
            }
            else l = mid + 1;
        }
        printf("%lld\n", r);
    }
    return 0;
}