题目描述
一个点每过一个单位时间就会向 4 个方向扩散一个距离,如图所示:两个点 a 、b 连通,记作 e(a,b),当且仅当 a 、b 的扩散区域有公共部分。连通块的定义是块内的任意两个点 u、v都必定存在路径
给定平面上的 n 个点,问最早什么时候它们形成一个连通块。
输入格式
第一行一个数 n ,以下 n 行,每行一个点坐标。
输出格式
输出仅一个数,表示最早的时刻所有点形成连通块。
样例
样例输入
2
0 0
5 5
样例输出
5
数据范围与提示
对于 20% 的数据,满足 1≤n≤5,1≤Xi,Yi≤50i,Yi≤50;
对于 100% 的数据,满足 1≤n≤50,1≤Xi,Yi≤10^9
#include<cstdio> #include<iostream> #include<algorithm> #include<cmath> using namespace std; const int maxn = 52; int G[maxn][maxn], n, xx[maxn], yy[maxn]; inline void init(int x){ for(int i=1; i<=n; ++i){ for(int j=1; j<=n; ++j) G[i][j] = 0; G[i][i] = 1; } for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) if(abs(xx[i] - xx[j]) + abs(yy[i] - yy[j]) <= x << 1) G[i][j] = 1; } inline void floyd(){ for(int k=1; k<=n; ++k) for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) if(G[i][k] && G[k][j]) G[i][j] = 1; } inline bool deal(int x){ init(x); floyd(); int judge = 1; for(int i=1; i<=n; i++) judge &= G[1][i]; return judge; } int main(void) { cin >> n; for(int i=1; i<=n; ++i) cin >> xx[i] >> yy[i]; int l = 1, r = 1000000000; while(l < r){ int mid = (l + r) >> 1; if(deal(mid)) r = mid; else l = mid + 1; } cout << l << endl; }
思路
二分+连边建图+floyd
i,Yi≤109。