扩散
洛谷P1661
分析
二分(寻找最小的时间)+并查集(检验是否构成连通块)
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| #include <cstdio> #include <cmath> #include <cstring>
#define LL long long
using namespace std;
const int MAXN = 55;
struct node { LL x; LL y; } nodes[MAXN];
int n, dict[MAXN]; LL left = 0, right = 1e9;
LL distance (node a, node b) { return abs(a.x - b.x) + abs(a.y - b.y); }
int zuisu (int x) { if (dict[x] == x) return x; return zuisu(dict[x]); }
bool check (LL x) { memset(dict, 0, sizeof(dict)); for (int i = 1; i <= n; i++) { dict[i] = i; } for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) { if (distance(nodes[i], nodes[j]) <= x * 2) { LL xx = zuisu(i); LL yy = zuisu(j); dict[xx] = yy; } } } int sum = 0; for (int i = 1; i <= n; i++) { if (dict[i] == i) sum++; return (sum == 1); }
int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%lld%lld", &nodes[i].x, &nodes[i].y); } int ans; while (right >= left) { LL mid = (right + left) >> 1; if (check(mid)) { right = mid - 1; ans = mid; } else left = mid + 1; } printf("%lld", ans); return 0; }
|