一本通 1.2 练习 2【扩散】

题目linkhttps://loj.ac/problem/10015

这道题虽说是二分里的,但是我没用二分的做法。

首先我的想法是直接找到任意两点之间的最大距离即可,但是后来写完交上去发现不对,之后分析了一下发现两个点成为同一个连通块是可以通过另外一个连通块更新距离的,因为另一个连通块也可以扩散,有点类似$Floyd$。

更新完之后可以直接像第一个思路一样算了,更新的时间就是最大距离 $+$ $1$ 再 $÷$ $2$,很容易证明。

 1 #include <bits/stdc++.h>
 2 #define INF 0x3f3f3f3f
 3 using namespace std;
 4 int n, x[60], y[60], ans, f[60][60];
 5 int cal(int ax, int ay, int bx, int by) {return abs(ax - bx) + abs(ay - by);}
 6 int main()
 7 {
 8     scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d %d", &x[i], &y[i]);
 9     for(int i = 1; i <= n; ++i)
10         for(int j = 1; j <= n; ++j)
11             f[i][j] = cal(x[i], y[i], x[j], y[j]);
12     for(int k = 1; k <= n; ++k)
13         for(int i = 1; i <= n; ++i)
14             for(int j = 1; j <= n; ++j)
15                 f[i][j] = min(f[i][j], max(f[i][k], f[k][j]));
16     for(int i = 1; i <= n; ++i)
17         for(int j = 1; j <= n; ++j)
18             ans = max(ans, f[i][j]);
19     printf("%d", (ans + 1) >> 1);
20     return 0;
21 }
原文地址:https://www.cnblogs.com/qqq1112/p/13910987.html