// PA2025, @mjm, r1a-tel
#include <cstdio>
#include <algorithm>
using namespace std;
inline int nextInt() { int n; scanf("%d", &n); return n; }
int myMin(int a, int b) { return a <= b ? a : b; }
int myMax(int a, int b) { return a >= b ? a : b; }
const int N = 400 + 9;
const int INF = N * N + 9; // any >n
int n;
char buf[N][N];
int dist[N][N];
int p1[N * N];
int p2[N * N];
int order[N * N];
int s1[N * N];
int s2[N * N];
int pcnt;
struct PairOrder { bool operator()(const int& a, const int& b) const {
return dist[p1[a]][p2[a]] > dist[p1[b]][p2[b]];
}};
int solve() {
// floyd-warshall
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i != j) {
if (buf[i][j] == '1')
dist[i][j] = 1;
else
dist[i][j] = INF;
}
}
}
for (int k = 0; k < n; ++k)
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (dist[i][j] > dist[i][k] + dist[k][j])
dist[i][j] = dist[i][k] + dist[k][j];
// prepare pair order
{
pcnt = 0;
for (int x = 0; x < n; ++x) {
for (int y = x + 1; y < n; ++y) {
p1[pcnt] = x;
p2[pcnt] = y;
++pcnt;
}
}
for (int i = 0; i < pcnt; ++i) {
order[i] = i;
}
PairOrder comparator;
sort(order, order + pcnt, comparator);
for (int i = 0; i < pcnt; ++i) {
s1[i] = p1[order[i]];
s2[i] = p2[order[i]];
}
s1[pcnt] = s2[pcnt] = 0; // dist[.][.] == 0!
}
// solution
int res = INF;
// for each teleport x--y
for (int ixy=0; ixy<pcnt; ++ixy) {
int x = s1[ixy];
int y = s2[ixy];
int cur = 0;
// for each path i--j
for (int iij = 0; iij < pcnt; ++iij) {
int i = s1[iij];
int j = s2[iij];
int distIJ = dist[i][j];
if (distIJ <= cur) break;
if (res <= cur) break;
// calculate best dist i--j
distIJ = myMin(distIJ, dist[i][x] + dist[y][j]);
distIJ = myMin(distIJ, dist[i][y] + dist[x][j]);
cur = myMax(cur, distIJ);
}
res = myMin(res, cur);
}
return res;
}
int main() {
int TC = nextInt();
for (int tc = 0; tc < TC; ++tc) {
n = nextInt();
for (int i = 0; i < n; ++i)
scanf("%s", buf[i]);
int res = solve();
printf("%d\n", res);
}
return 0;
}
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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | // PA2025, @mjm, r1a-tel #include <cstdio> #include <algorithm> using namespace std; inline int nextInt() { int n; scanf("%d", &n); return n; } int myMin(int a, int b) { return a <= b ? a : b; } int myMax(int a, int b) { return a >= b ? a : b; } const int N = 400 + 9; const int INF = N * N + 9; // any >n int n; char buf[N][N]; int dist[N][N]; int p1[N * N]; int p2[N * N]; int order[N * N]; int s1[N * N]; int s2[N * N]; int pcnt; struct PairOrder { bool operator()(const int& a, const int& b) const { return dist[p1[a]][p2[a]] > dist[p1[b]][p2[b]]; }}; int solve() { // floyd-warshall for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (i != j) { if (buf[i][j] == '1') dist[i][j] = 1; else dist[i][j] = INF; } } } for (int k = 0; k < n; ++k) for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (dist[i][j] > dist[i][k] + dist[k][j]) dist[i][j] = dist[i][k] + dist[k][j]; // prepare pair order { pcnt = 0; for (int x = 0; x < n; ++x) { for (int y = x + 1; y < n; ++y) { p1[pcnt] = x; p2[pcnt] = y; ++pcnt; } } for (int i = 0; i < pcnt; ++i) { order[i] = i; } PairOrder comparator; sort(order, order + pcnt, comparator); for (int i = 0; i < pcnt; ++i) { s1[i] = p1[order[i]]; s2[i] = p2[order[i]]; } s1[pcnt] = s2[pcnt] = 0; // dist[.][.] == 0! } // solution int res = INF; // for each teleport x--y for (int ixy=0; ixy<pcnt; ++ixy) { int x = s1[ixy]; int y = s2[ixy]; int cur = 0; // for each path i--j for (int iij = 0; iij < pcnt; ++iij) { int i = s1[iij]; int j = s2[iij]; int distIJ = dist[i][j]; if (distIJ <= cur) break; if (res <= cur) break; // calculate best dist i--j distIJ = myMin(distIJ, dist[i][x] + dist[y][j]); distIJ = myMin(distIJ, dist[i][y] + dist[x][j]); cur = myMax(cur, distIJ); } res = myMin(res, cur); } return res; } int main() { int TC = nextInt(); for (int tc = 0; tc < TC; ++tc) { n = nextInt(); for (int i = 0; i < n; ++i) scanf("%s", buf[i]); int res = solve(); printf("%d\n", res); } return 0; } |
English