题目链接:https://vjudge.net/problem/uva-11624
两遍BFS,第一遍把每个点着火的时间记录下来存在t数组里,然后第二遍BFS就是搜索解了。好像暑假集训网络赛遇到个类似的题目,当时没做出来。
/*
* @Author: SamsonHo
* @Date: 2018-10-06-23.49
* @URL:https://vjudge.net/problem/UVA-11624
* @Note:
*/
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int MAXN = 1e3+10;
queue<pair<int,int> > que;
int r,c,t[MAXN][MAXN];
int b[MAXN][MAXN];
char g[MAXN][MAXN];
int dir[] = {0,-1,0,1,0};
void bfs1()
{
memset(t,-1,sizeof t);
while(!que.empty()) que.pop();
for(int i = 1; i <= r; ++i)
{
for(int j = 1; j <= c; ++j)
{
if(g[i][j] == 'F')
{
t[i][j] = 0;
que.push(make_pair(i,j));
}
}
}
pair<int,int> top;
while(!que.empty())
{
top = que.front();
que.pop();
int x = top.first,y = top.second;
for(int i = 1; i <= 4; ++i)
{
int nx = x+dir[i-1],ny = y+dir[i];
if(nx<1 || nx>r || ny<1 || ny>c) continue;
if(t[nx][ny] != -1 || g[nx][ny] == '#') continue;
t[nx][ny] = t[x][y]+1;
que.push(make_pair(nx,ny));
}
}
}
int bfs2()
{
memset(b,-1,sizeof b);
while(!que.empty()) que.pop();
for(int i = 1; i <= r; ++i)
{
for(int j = 1; j <= c; ++j)
{
if(g[i][j] == 'J')
{
b[i][j] = 0;
que.push(make_pair(i,j));
}
}
}
pair<int,int> top;
while(!que.empty())
{
top = que.front();
que.pop();
int x = top.first,y = top.second;
if(x==1 || y==1 || x==r || y==c) return b[x][y]+1;
for(int i = 1; i <= 4; ++i)
{
int nx = x+dir[i-1],ny = y+dir[i];
if(nx<1 || nx>r || ny<1 || ny>c || b[nx][ny]!=-1) continue;
if(t[nx][ny] != -1 && t[nx][ny] <= b[x][y]+1 || g[nx][ny] == '#') continue;
b[nx][ny] = b[x][y]+1;
que.push(make_pair(nx,ny));
}
}
return -1;
}
int main(void)
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&r,&c);
// getchar();
for(int i = 1; i <= r; ++i)
scanf("%s",g[i]+1);
bfs1();
int ans = bfs2();
if(ans == -1)
puts("IMPOSSIBLE");
else
printf("%d\n",ans);
}
}