UVA 11624 Fire! 【bfs】

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.

Sample Input

2

4 4

####

#JF#

#..#

#..#

3 3

###

#J.

#.F

Output Specification

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

Output for SampleInput

3

IMPOSSIBLE


题意:

一个男人在迷宫里工作,有一天,迷宫里的几块地突然着火了,火势在水平方向和竖直方向上蔓延。每一个单位时间蔓延一格。

这个男人想要逃出迷宫,他也只能向水平方向和竖直方向逃跑。每单位时间移动一格。‘#’代表墙壁,这个人无法穿过墙壁,火势也无法蔓延到墙壁。问这个男人是否能逃离迷宫,如果能,输出最少时间。如果不能,输出impossible。

 

这题需要注意的是,起火点不唯一

 

我们先对所有起火点进行bfs,计算出火势到达每一个格子所需要的时间。

然后在对这个人的起点进行bfs,如果这个人到达某个格子所需要的时间比火势蔓延到该格子所需要的时间早。那么这个人可以顺利通过这个格子。

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
using namespace std;
#define LL long long
#define M(a,b) memset(a,b,sizeof(a))
const int MAXN = 1e3+5;
const int INF =  0x3f3f3f3f;
int X[5] = {0,0,0,-1,1};
int Y[5] = {0,1,-1,0,0};
queue<pair<int,int> >q;
int vis1[MAXN][MAXN];
int vis2[MAXN][MAXN];
int MAP[MAXN][MAXN];
vector<pair<int,int> >v;///存储所有着火点
int jx,jy;
int r,c;
void bfs1()///算出火势蔓延到所有格子的时间
{
    for(int i=0; i<v.size(); i++)
    {
        q.push(make_pair(v[i].first,v[i].second));
        vis1[v[i].first][v[i].second] = 1;
    }

    while(!q.empty())
    {
        int x1 = q.front().first;
        int y1 = q.front().second;
        q.pop();
        for(int i=1; i<=4; i++)
        {
            int xx = x1 +X[i];
            int yy = y1 +Y[i];
            if(xx>=1&&xx<=r&&yy>=1&&yy<=c&&vis1[xx][yy]==0&&MAP[xx][yy]!=-1)
            {
                vis1[xx][yy] = vis1[x1][y1]+1;
                q.push(make_pair(xx,yy));
            }
        }
    }
}
int bfs2(int x,int y)///计算出这个人到达所有格子的时间
{
    while(!q.empty()) q.pop();
    q.push(make_pair(x,y));
    vis2[x][y] = 1;
    while(!q.empty())
    {
        int x1 = q.front().first;
        int y1 = q.front().second;
        if((x1==1||x1==r||y1==1||y1==c))///到达边界时,逃脱成功
        {
            return vis2[x1][y1];
        }
        q.pop();
        for(int i=1; i<=4; i++)
        {
            int xx = x1 +X[i];
            int yy = y1 +Y[i];
            if(xx>=1&&xx<=r&&yy>=1&&yy<=c&&vis2[xx][yy]==0&&MAP[xx][yy]!=-1)
            {
                vis2[xx][yy] = vis2[x1][y1]+1;
                if(vis2[xx][yy]>=vis1[xx][yy]&&vis1[xx][yy]!=0) ///人到达该格子的时间要早于火到达的,且是火能到达的。
                    continue;
                q.push(make_pair(xx,yy));
            }
        }
    }
    return -1;
}
void init()
{
    M(vis2,0);
    M(vis1,0);
    v.clear();
    while(!q.empty()) q.pop();
}
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        init();
        scanf("%d %d",&r,&c);
        for(int i=1; i<=r; i++)
        {
            for(int j=1; j<=c; j++)
            {
                char temp;
                cin>>temp;
                if(temp=='#') MAP[i][j] = -1;
                if(temp=='.') MAP[i][j] = 1;
                if(temp=='F')
                {
                    v.push_back(make_pair(i,j));///着火点不唯一
                }
                if(temp=='J')
                {
                    jx = i;
                    jy = j;
                }
            }
        }
        bfs1();
        int ans = bfs2(jx,jy);
        if(ans==-1)
        {
            printf("IMPOSSIBLE\n");
        }
        else
        {
            printf("%d\n",ans);
        }
    }
    return 0;
}
//2
//3 4
//F#..
//#J..
//....

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章