bfs
枚举两个起点(可能相同)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
struct Point
{
int r, c;
Point(int r=0,int c=0): r(r), c(c) {}
};
const int MAX = 10;
const int SUP = 1999999999;
int n;
int m;
int tot;
bool board[MAX+2][MAX+2];
int firetime[MAX+2][MAX+2];
vector<Point> grass;
int readchar()
{
int ch;
while (ch = getchar())
{
if (ch == '.' || ch == '#')
return ch;
}
}
int read_board()
{
memset(board, 0, sizeof(board));
grass.clear();
scanf("%d%d\n", &n, &m);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
if (readchar() == '#')
{
board[i][j] = true;
grass.push_back(Point(i, j));
}
}
return grass.size();
}
bool inside(Point u)
{
return (u.r >= 1 && u.r <= n && u.c >= 1 && u.c <= m);
}
int _bfs(int r, int c, int rr, int cc)
{
static const int ROW[] = {-1, 0, 1, 0};
static const int COL[] = {0, 1, 0, -1};
queue<Point> q;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
firetime[i][j] = SUP;
q.push(Point(r, c));
if (rr != r || cc != c)
q.push(Point(rr,cc));
firetime[r][c] = firetime[rr][cc] = 0;
int cnt = 0;
int cost = 0;
while (!q.empty())
{
Point u = q.front();
q.pop();
cnt++;
for (int i = 0; i < 4; i++)
{
Point v = Point(u.r + ROW[i], u.c + COL[i]);
if (inside(v) && board[v.r][v.c] && firetime[v.r][v.c] > firetime[u.r][u.c] + 1)
{
cost = max(cost, firetime[v.r][v.c] = firetime[u.r][u.c] + 1);
q.push(v);
}
}
}
return (cnt == tot) ? cost : -1;
}
int _enumberate()
{
int ret = -1;
int tmp;
for (int i = 0; i < tot; i++)
{
for (int j = i; j < tot; j++)
{
if ((tmp = _bfs(grass[i].r, grass[i].c, grass[j].r, grass[j].c)) != -1)
{
if (ret == -1)
ret = tmp;
else
ret = min(ret, tmp);
}
}
}
return ret;
}
int main()
{
int T;
int kase = 0;
int ans = -1;
scanf("%d", &T);
while (++kase <= T)
{
tot = read_board();
ans = _enumberate();
printf("Case %d: %d\n", kase, ans);
}
return 0;
}