一定要注意联通两点后,新的连通块的直径并不一定是联通通过这两个点的最长距离,还可能是原来连通块的直径。
因为这个,WA了好久……真心没想到
Compiling... Compile: OK Executing... Test 1: TEST OK [0.005 secs, 3724 KB] Test 2: TEST OK [0.003 secs, 3724 KB] Test 3: TEST OK [0.003 secs, 3724 KB] Test 4: TEST OK [0.005 secs, 3724 KB] Test 5: TEST OK [0.070 secs, 3724 KB] Test 6: TEST OK [0.068 secs, 3724 KB] Test 7: TEST OK [0.065 secs, 3724 KB] Test 8: TEST OK [0.076 secs, 3724 KB] Test 9: TEST OK [0.068 secs, 3724 KB] All tests OK.
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
int n;
struct node
{
double x, y;
node(int X, int Y)
{
x = (double)X;
y = (double)Y;
}
node(){}
}a[200];
char s[200][200];
double g[200][200];
vector<int>A,B;
double dis(node A, node B)
{
return sqrt((A.x - B.x)*(A.x - B.x) + (A.y - B.y)*(A.y - B.y));
}
void init()
{
cin >> n;
for (int i = 0; i != n; ++ i)
{
int x, y;
cin >> x >> y;
a[i] = node(x, y);
}
for (int i = 0; i != n; ++ i) scanf("%s", s[i]);
//g数组初始化为-1
for (int i = 0; i != n; ++ i)
for (int j = 0; j != n; ++ j) g[i][j] = -1;
//初始化g数组的一些值
for (int i = 0; i != n; ++ i)
for (int j =0; j != n; ++ j)
if (s[i][j] == '1')
g[i][j] = dis(a[i], a[j]);
//自己到自己的距离为0
for (int i = 0; i != n; ++ i) g[i][i] = 0;
//求最短路
for (int k = 0; k != n; ++ k)
for (int i = 0; i != n; ++ i)
for (int j = 0; j != n; ++ j)
if (g[i][k] != -1 && g[k][j] != -1)
{
if (g[i][j] == -1)
{
g[i][j] = g[i][k] + g[k][j];
}
else g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
}
}
void doit()
{
double ans = 0x7fffffff;
double tans = -1;
for (int i = 0; i != n; ++ i)
for (int j = 0; j != n; ++ j) tans = max(tans, g[i][j]);
for (int i = 0; i != n; ++ i)
for (int j = 0; j != n; ++ j)
{
//i ,j
if (g[i][j] != -1) continue;
double disA = -1, disB = -1;
for (int k = 0; k != n; ++ k) disA = max(disA, g[i][k]);
for (int k = 0; k != n; ++ k) disB = max(disB, g[j][k]);
double tmp = disA + disB + dis(a[i], a[j]);
if (ans > tmp)
{
ans = tmp;
}
}
if (ans < tans) ans = tans;
printf("%lf\n", ans);
}
int main()
{
init();
doit();
return 0;
}