UVA - 11624 Fire!

Fire! UVA - 11624 

题面:点链接看

题意:一个平面迷宫中有一个人,迷宫中有些点起火了,火和人每个单位时间只能向相邻的格子移动,

            其中有一些空间被墙壁占据,问这个人在不背或烧到的情况下,离开迷宫的最快时间。要注意火可能不止一处,但是人只有一个

思路:
两次BFS,首先把开始的F(火)入队,然后进行BFS 并用times数组记录到达每个位置的时间(初始化为INF,不可达则为INF),然后进行逃跑路线的BFS,当满足基本条件(不越界,未被访问),再满足到达某点时间小于该点的times,则说明在火到达之前,到此位置。如此进行,知道到达边界或者队列为空也没到达(IMPOSSIBLE)。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=1005;
int T;
int n,m;
int si,sj;
int ans;
char s[maxn][maxn];
int timee[maxn][maxn];
bool vis[maxn][maxn];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
struct Node
{
    int x,y;
    int step;
};
Node now,temp,nex;
queue<Node>q;

void init()
{
    while(!q.empty())
        q.pop();
    memset(vis,false,sizeof(vis));
    memset(timee,INF,sizeof(timee));
    ans=0;
}
void prebfs()
{
    while(!q.empty())
    {
        temp=q.front();
        q.pop();
        for(int i=0;i<4;i++)
        {
            nex.x=temp.x+dx[i];
            nex.y=temp.y+dy[i];
            if(vis[nex.x][nex.y]==false&&s[nex.x][nex.y]=='.')
            {
                vis[nex.x][nex.y]=true;
                nex.step=temp.step+1;
                timee[nex.x][nex.y]=nex.step;
                q.push(nex);
            }
        }
    }
}
bool bfs()
{
    memset(vis,false,sizeof(vis));
    queue<Node>qq;
    now.x=si;now.y=sj;now.step=0;
    vis[si][sj]=true;
    qq.push(now);
    while(!qq.empty())
    {
        temp=qq.front();
        qq.pop();
        for(int i=0;i<4;i++)
        {
            nex.x=temp.x+dx[i];
            nex.y=temp.y+dy[i];
            if(nex.x<1||nex.y<1||nex.x>n||nex.y>m)
            {
                ans=temp.step+1;
                return true;
            }
            if(vis[nex.x][nex.y]==false&&s[nex.x][nex.y]=='.'&&temp.step+1<timee[nex.x][nex.y])
            {
                vis[nex.x][nex.y]=true;
                nex.step=temp.step+1;
                qq.push(nex);
            }
        }
    }
    return false;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        init();
        scanf("%d %d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%s",s[i]+1);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                if(s[i][j]=='F')
                {
                    now.x=i;now.y=j;
                    now.step=0;
                    vis[i][j]=true;
                    q.push(now);
                }
                if(s[i][j]=='J')
                {
                    si=i;sj=j;
                }
            }
        }
        prebfs();
        if(bfs())
            printf("%d\n",ans);
        else
            printf("IMPOSSIBLE\n");
    }
    return 0;
}

 

posted @ 2018-12-06 13:14  从让帝到the_rang  阅读(136)  评论(0编辑  收藏  举报