UVA11624---Fire(双bfs)

                                                  Fire

                                                                Time limit   1000 ms

Joe works in a maze. Unfortunately,portions of the maze have caught on fire, and the owner of the maze neglectedto create a fire escape plan. Help Joe escape the maze.

Given Joe's location in the maze and which squares of themaze are on fire, you must determine whether Joe can exit the maze before thefire reaches him, and how fast he can do it.

Joe and the fire each move one square per minute,vertically or horizontally (not diagonally). The fire spreads all fourdirections from each square that is on fire. Joe may exit the maze from anysquare that borders the edge of the maze. Neither Joe nor the fire may enter asquare that is occupied by a wall.

Input Specification

The first line of input contains a single integer, thenumber of test cases to follow. The first line of each test case contains thetwo integers R and C, separated byspaces, with 1 <= R,C <= 1000. Thefollowing R lines of the test case each contain one row of themaze. Each of these lines contains exactly C characters, andeach of these characters is one of:

·  #, a wall

·  ., a passable square

·  J, Joe's initialposition in the maze, which is a passable square

·  F, a square that is onfire

There will be exactly one J in each test case.

Output

For each test case, output a single line containing ‘IMPOSSIBLE’ if Joe cannot exit the maze before the fire reaches him, or an integer giving the earliest time Joe can safely exit the maze, in minutes.

Sample Input

2

4 4

####

#JF#

#..#

#..#

3 3

###

#J.

#.F

Sample Output

3

IMPOSSIBLE

这是十个月之前的题( ̄ェ ̄;) ,今天终于给补上了

看到这道题的第一想法是在一个bfs里面 人和火一起跑,火更新地图,如果人和火撞到一起就gg,写了一会,不好下手,那就只能分开成两个bfs了,因为火会影响人的路线,但是火的路线和到达某一个点的时间是固定的,所以很容易想到的思路就是先让火跑遍整个图,做好预处理,记下来火到达每个点的时间,然后在让人出发,如果人到达这个地方的时间小于火到达这个地方的时间,那么是可以通过的,否则这个点是不能走的,如果人可以跑到地图之外,就安全撤离了

但是这道题始终没能AC,去网上扒拉了一下才知道坑点在题目第一行的那个单词 portions 就是说起火点不一定只有一个,可能是多个,就不能简单的存火的起始点了,那就直接入队列吧,但是全局队列不要忘了初始化

还有就是不要用time作为变量名,应该是个保留字吧,编译过不去,反正别用就对了。。。。

#include<cstdio>
#include<string>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
inline int _read() {
    char ch = getchar();
    int sum = 0;
    while (!(ch >= '0' && ch <= '9'))ch = getchar();
    while (ch >= '0' && ch <= '9')sum = sum * 10 + ch - 48, ch = getchar();
    return sum;
}
const int inf=0x3f3f3f3f;
const int mm=1005;

int t;
int n,m;
char mp[mm][mm];
int book[mm][mm];
int tim[mm][mm];
int to[4][2]={0,1,1,0,0,-1,-1,0};
int sx,sy,fx,fy; 
struct node{
	int x,y;
	int step;
	node(int a,int b,int c):x(a),y(b),step(c){}
};
queue<node>q;

void bfs_F(){
	while(!q.empty()){
		node pre=q.front();
		q.pop();
		for(int i=0;i<4;i++){
			int nx=pre.x+to[i][0];
			int ny=pre.y+to[i][1];
			if(nx<0||nx>=n||ny<0||ny>=m||book[nx][ny]||mp[nx][ny]=='#')
				continue;
			book[nx][ny]=1;
			tim[nx][ny]=pre.step+1;
			q.push(node(nx,ny,pre.step+1)); 
		}
	}
}

int bfs_J(){
	while(!q.empty())
		q.pop();
	q.push(node(sx,sy,0));
	while(!q.empty()){
		node pre=q.front();
		q.pop();
		if(pre.x<0||pre.x>=n||pre.y<0||pre.y>=m)
			return pre.step;
		for(int i=0;i<4;i++){
			int nx=pre.x+to[i][0];
			int ny=pre.y+to[i][1];
			if(mp[nx][ny]!='#'&&pre.step+1<tim[nx][ny]){
				mp[nx][ny]='#';
				q.push(node(nx,ny,pre.step+1));
			}
		}	
	}
	return -1;
}

int main()
{
	cin>>t;
	while(t--){
		while(!q.empty())
			q.pop();
		mem(book,0);
		mem(tim,inf);
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;i++){
			scanf("%s",mp[i]);
			for(int j=0;j<m;j++)
				if(mp[i][j]=='J')
					sx=i,sy=j;
				else if(mp[i][j]=='F'){//可能有多个起火点!!! 
					q.push(node(i,j,0));
					book[i][j]=1; 
					tim[i][j]=0;
				}
		}
		bfs_F();	
		int res=bfs_J();
		if(res==-1)
			printf("IMPOSSIBLE\n");
		else 
			printf("%d\n",res);
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值