UVA 11624 Fire!(BFS)

预处理一下每个点的着火事件。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=1000+5;
char map[maxn][maxn];
int fire[maxn][maxn],vis[maxn][maxn];
int r,c;
int sx,sy;
int dx[4]={-1,0,1,0};
int dy[4]={0,-1,0,1};
struct node{
    int x,y,t;
};
#define ss(x) scanf("%d",&x)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
bool inside(int x,int y) {return x>=1&&x<=r&&y>=1&&y<=c;}
void build_fire_time()
{
    memset(fire,0x7f,sizeof(fire));
    memset(vis,0,sizeof(vis));
    queue<node> q;
    rep(i,1,r) rep(j,1,c) if(map[i][j]=='F') {q.push((node){i,j,1});fire[i][j]=1;vis[i][j]=1;}
    while(!q.empty())
    {
        node last=q.front();q.pop();
        rep(i,0,3){
            node now;
            now.x=last.x+dx[i];
            now.y=last.y+dy[i];
            now.t=last.t+1;
            if(inside(now.x,now.y)&&map[now.x][now.y]!='#'&&!vis[now.x][now.y]) {
                vis[now.x][now.y]=1;
                fire[now.x][now.y]=min(fire[now.x][now.y],now.t);q.push(now);
            }
        }
    }
}
void findsorce(){
    rep(i,1,r) rep(j,1,c) if(map[i][j]=='J') {sx=i;sy=j;return ;}
}
void findpath(){
    memset(vis,0,sizeof(vis));
    queue<node> q;
    q.push((node){sx,sy,1});
    vis[sx][sy]=1;
    while(!q.empty())
    {
        node last=q.front();q.pop();
        if(last.x==1||last.x==r||last.y==1||last.y==c) {printf("%d\n",last.t);return ;}
        rep(i,0,3){
            int x,y,t;
            x=last.x+dx[i];
            y=last.y+dy[i];
            t=last.t+1;
            if(inside(x,y)&&map[x][y]!='#'&&!vis[x][y]&&t<fire[x][y]) {vis[x][y]=1;q.push((node){x,y,t});}
        }
    }
    printf("IMPOSSIBLE\n");
}
int main()
{
    int t;ss(t);
    while(t--)
    {
        ss(r);ss(c);
        rep(i,1,r) scanf("%s",map[i]+1);
        build_fire_time();
        findsorce();
        findpath();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值