UVA 11624 Fire! 两次BFS求解

题目链接:http://uva.onlinejudge.org/external/116/11624.pdf

题意:给定一个迷宫和一些着火点,火会不断想四周蔓延,求一条逃出迷宫的最短路径。

思路:先用一次BFS求出火蔓延到每个点的最短时间,可以把#的时间设为0,'.'火到不了的,设为oo(这里应该注意一下,WA了一次)。后面就是常规的BFS求最短路了。


代码:

#include<iostream>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>

#define LL long long
#define INF 0x7fffffff

using namespace std;
struct node{
    int x,y,step;
};

char Map[1010][1010];
int vis[1010][1010],dis[1010][1010];
int R,C,J[2];
vector<int> F;

int d[][2]={1,0,-1,0,0,-1,0,1};

void bfs(){//求出火蔓延到每个点的时间
    memset(vis,0,sizeof(vis));
    memset(dis,0,sizeof(dis));
    queue<node> Q;
    for(int i=0;i<(int)F.size();i++)
        Q.push((node){F[i]/R,F[i]%R,0}),vis[F[i]/R][F[i]%R]=1;
    while(!Q.empty()){
        node tp=Q.front();
        Q.pop();
        for(int p=0;p<4;p++){
            int tx=tp.x+d[p][0],ty=tp.y+d[p][1];
            if(tx<0 || ty<0 || tx>=R || ty>=C) continue;
            if(Map[tx][ty]!='.' || vis[tx][ty]) continue;
            dis[tx][ty]=tp.step+1;
            Q.push((node){tx,ty,tp.step+1});
            vis[tx][ty]=1;
        }
    }
    for(int i=0;i<R;i++) for(int j=0;j<C;j++)//火蔓延不到的点且为通行路径,时间置为oo
        if(Map[i][j]=='.' && !vis[i][j]) dis[i][j]=INF;
}

void BFS(){//现在就是常规的BFS求最短路了
    memset(vis,0,sizeof(vis));
    queue<node> Q;
    Q.push((node){J[0],J[1],0});
    vis[J[0]][J[1]]=1;
    while(!Q.empty()){
        node tp=Q.front();
        if(tp.x==0 || tp.y==0 || tp.x==R-1 || tp.y==C-1) {cout<<tp.step+1<<endl;return;}
        Q.pop();
        for(int p=0;p<4;p++){
            int tx=tp.x+d[p][0],ty=tp.y+d[p][1];
            if(tx<0 || ty<0 || tx>=R || ty>=C) continue;
            if(vis[tx][ty] || tp.step+1>=dis[tx][ty]) continue;
            vis[tx][ty]=1;
            Q.push((node){tx,ty,tp.step+1});
        }
    }
    cout<<"IMPOSSIBLE\n";
}

int main(){
    //freopen("D:\\in.txt","r",stdin);
    int T;cin>>T;
    while(T--){
        cin>>R>>C; F.clear();
        getchar();
        for(int i=0;i<R;i++){
            for(int j=0;j<C;j++){
                scanf("%c",&Map[i][j]);
                if(Map[i][j]=='J') J[0]=i,J[1]=j;
                else if(Map[i][j]=='F') F.push_back(i*R+j);
            }
            getchar();
        }
        bfs();
        BFS();
    }
    return 0;
}



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值