思路
这道题应该是和前面做的杭电那个差不多,先让火跑bfs把到达每一块空地的时间存下来,然后让人去跑bfs看看能不能比火先到这个点,如果能就可以过去,如果人走到这里比火还慢等着被烧死,注意有多个起火点。 UVA的题目一道题判3个小时出结果,刷的比较少。
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int inf = 1e9;
const int maxn = 1050;
struct node{
int x,y;
int s;
};
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
char map[maxn][maxn];
bool visited[maxn][maxn];
int sum[maxn][maxn];
queue<node> q;
void clear_queue()
{
memset(visited,false,sizeof(visited));
while(!q.empty()){
q.pop();
}
}
void bfs_fire(int m,int n)
{
while(!q.empty()){
node ptr = q.front(),p;
q.pop();
for(int i = 0;i < 4;i++){
p.x = ptr.x + dx[i];
p.y = ptr.y + dy[i];
p.s = ptr.s + 1;
if(p.x < 0 || p.x >= m || p.y < 0 || p.y >= n || map[p.x][p.y] == 'F'
|| map[p.x][p.y] == '#' || visited[p.x][p.y]){
continue;
}
sum[p.x][p.y] = p.s;
visited[p.x][p.y] = true;
q.push(p);
}
}
}
int bfs_person(int m,int n)
{
while(!q.empty()){
node ptr = q.front(),p;
q.pop();
if(ptr.x == 0 || ptr.y == 0 || ptr.x == m-1 || ptr.y == n-1){
return ptr.s + 1;
}
for(int i = 0;i < 4;i++){
p.x = ptr.x + dx[i];
p.y = ptr.y + dy[i];
p.s = ptr.s + 1;
if(map[p.x][p.y] == '#' || map[p.x][p.y] == 'F' || p.s >= sum[p.x][p.y] || visited[p.x][p.y]){
continue;
}
visited[p.x][p.y] = true;
q.push(p);
}
}
return -1;
}
int main()
{
int t,m,n;
node p;
cin>>t;
while(t--){
clear_queue();
cin>>m>>n;
int p_x,p_y;
for(int i = 0;i < m;i++){
for(int j = 0;j < n;j++){
cin>>map[i][j];
if(map[i][j] == 'J'){
p_x = i;p_y = j;
}
if(map[i][j] == 'F'){
p.x = i;p.y = j;p.s = 0;
visited[p.x][p.y] = true;
q.push(p);
}
sum[i][j] = inf;
}
}
bfs_fire(m,n);
clear_queue();
p.x = p_x;p.y = p_y;p.s = 0;
visited[p.x][p.y] = true;
q.push(p);
int ans = bfs_person(m,n);
if(ans == -1){
printf("IMPOSSIBLE\n");
}
else{
printf("%d\n",ans);
}
}
return 0;
}
愿你走出半生,归来仍是少年~