1. 程式人生 > >UVA11624 Fire!(兩次bfs,第一次預處理)

UVA11624 Fire!(兩次bfs,第一次預處理)

題意翻譯

大火蔓延的迷宮

題目大意 你的任務是幫助Joe走出一個大火蔓延的迷宮。Joe每分鐘可以走到上下左右4個方向的相鄰格子之一,而所有著火的格子都會四周蔓延(即如果某個空格子與著火格子有公共邊,則下一分鐘這個空格子將著火)。迷宮中有一些障礙格,Joe和火都無法進入。當Joe走到一個迷宮的邊界格子時,我們認為他已經出了迷宮。

輸入資料 第一行為資料組數T。每一組測試資料格式如下: 第一行為兩個整數R和C(1<=R,C<=1000)。以下R行每行有C個字元,即迷宮,其中“#”表示牆和障礙物,“.”表示空地,“J”是joe的初始位置(也就是空地),”F”是著火格子。每組資料的迷宮中恰好有一個格是”J”。

輸出資料 對於每組測試資料,如無法走出迷宮,則輸出IMPOSSIBLE,否則輸出走出迷宮的最短時間(單位:分鐘)。

感謝@hicc0305 提供的翻譯

 

輸入輸出樣例

輸入樣例#1: 複製

2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F

思路:首先,這個題目如果著火點不會傳染,那麼這個題就是一個類似於最短迷宮的題目, 

現在著火點傳染,那麼我們可以先將某時間內這點的著火情況表示出來,也就是第一個bfs的作用,

後面的第二個bfs就往常一樣了。。。

程式碼:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<stack>
#define inf 0x3f3f3f3f
#define maxn 1050
using namespace std;

struct node
{
    int x,y,t;
    node(int x,int y,int t):x(x),y(y),t(t) {}
};

queue<node>q;
int t,n,m,p[maxn][maxn],vis[maxn][maxn],sx,sy;
int dx[]= {0,0,1,-1};
int dy[]= {1,-1,0,0};
char a[maxn][maxn];

void init_bfs() //預處理時間和著火點
{
    while(!q.empty())
    {
        node u=q.front();
        q.pop();
        for(int i=0; i<4; i++)
        {
            int vx=u.x+dx[i],vy=u.y+dy[i];
            if((vx>=1&&vx<=n&&vy>=1&&vy<=m)&&a[vx][vy]!='#'&&p[vx][vy]==inf)
            {
                q.push(node(vx,vy,0));
                p[vx][vy]=p[u.x][u.y]+1;
            }
        }
    }
}

void bfs()
{
    while(!q.empty())
        q.pop();
    q.push(node(sx,sy,0));
    vis[sx][sy]=1;
    while(!q.empty())
    {
        node u=q.front();
        q.pop();
        if(u.x==n||u.x==1||u.y==1||u.y==m)
        {
            printf("%d\n",u.t+1);
            return;
        }
        for(int i=0; i<4; i++)
        {
            int vx=u.x+dx[i],vy=u.y+dy[i];
            if((vx>=1&&vx<=n&&vy>=1&&vy<=m)&&a[vx][vy]!='#'&&!vis[vx][vy]&&(u.t+1<p[vx][vy]))
            {
                q.push(node(vx,vy,u.t+1));
                vis[vx][vy]=1;
            }
        }
    }
    puts("IMPOSSIBLE");
    return;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        while(!q.empty()) q.pop();
        memset(vis,0,sizeof(vis));
        memset(p,inf,sizeof(p));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if(a[i][j]=='J') sx=i,sy=j;
                if(a[i][j]=='F')
                {
                    q.push(node(i,j,0));
                    p[i][j]=0;
                }
            }
            init_bfs();
            bfs();
    }
    return 0;
}