文章链接
- 分析:
火和人的行动是互不影响的,应该独立进行。先进行火的bfs,记录一下火到每个点的步数,在人的bfs时到相应的格子时必须小于这个数
const int MAXN = 1100;
struct Node
{
int x, y, foot;
Node (int x = 0, int y = 0, int foot = 0) : x(x), y(y), foot(foot){}
} people;
char m[MAXN][MAXN];
int step[MAXN][MAXN];
queue<Node> q;
int kase, a, b;
int dx[] = {0, 0, -1, 1};
int dy[] = {-1, 1, 0, 0};
inline void init()
{
while (!q.empty()) q.pop();
}
void bfs_fire()
{
Node t;
while (!q.empty())
{
t = q.front();
q.pop();
REP(i, 4)
{
int tx = t.x + dx[i];
int ty = t.y + dy[i];
if (m[tx][ty] == '.' && step[tx][ty] == INF)
{
step[tx][ty] = t.foot + 1;
q.push(Node(tx, ty, t.foot + 1));
}
}
}
}
bool bfs_people(Node& ans)
{
while (!q.empty())
{
ans = q.front();
q.pop();
if (ans.x == 1 || ans.x == a || ans.y == 1 || ans.y == b)
return true;
REP(i, 4)
{
int tx = ans.x + dx[i];
int ty = ans.y + dy[i];
if (m[tx][ty] == '.' && ans.foot + 1 < step[tx][ty])
{
m[tx][ty] = 'J';
q.push(Node(tx, ty, ans.foot + 1));
}
}
}
return false;
}
int main()
{
// freopen("in.txt", "r", stdin);
RI(kase);
REP(kk, kase)
{
CLR(step, INF);
CLR(m, '#');
init();
RII(a, b);
FE(i, 1, a) FE(j, 1, b)
{
cin >> m[i][j];
if (m[i][j] == 'J')
{
people.x = i, people.y = j;
people.foot = 0;
m[i][j] = '.';
}
else if (m[i][j] == 'F')
{
step[i][j] = 0;
q.push(Node(i, j, 0));
m[i][j] = '.';
}
}
bfs_fire();
init();
q.push(people);
m[people.x][people.y] = 'J';
if (bfs_people(people))
cout << people.foot + 1 << endl;
else
cout << "IMPOSSIBLE" << endl;
}
return 0;
}