双向BFS--Uva-11624

题意:john要从迷宫里逃跑,迷宫里有着火的地方,并且火势可以蔓延,问john是否可以逃出来,如果可以输出最短时间。

思路:我觉得这道题很好,以前没做过,需要从两个方向进行搜索,首先对火进行处理,保存下火到达每个格子的时间,然后再对john进行bfs,在对john进行bfs是,只需要加一个条件,判断john到达每个格子的时间与原来火到达此地的时间,哪个大。

代码如下:

#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<climits>
using namespace std;
const int maxn=1010;
const int inf=100000000;
struct A
{
    int x,y,tim;
};
char maze[maxn][maxn];
int Time[maxn][maxn];
int vis[maxn][maxn];
int sx,sy;
int r,c;
int dx[]= {1,-1,0,0};
int dy[]= {0,0,1,-1};
queue<A> fire;
int ans;
void bfs(int num)
{
    A a;
    while(!fire.empty())
    {
        a=fire.front();
        fire.pop();
        if(num)
            if((a.x>=r)||(a.x<=1)||(a.y>=c)||(a.y<=1))
            {
                ans=min(a.tim,ans);
            }
        A b;
        for(int i=0; i<4; i++)
        {
            b.x=a.x+dx[i];
            b.y=a.y+dy[i];
            if(b.x>=1&&b.x<=r&&b.y>=1&&b.y<=c&&(maze[b.x][b.y]!='#')&&(!vis[b.x][b.y])&&(Time[b.x][b.y]>a.tim+1))
            {
                b.tim=a.tim+1;
                Time[b.x][b.y]=b.tim;
                vis[b.x][b.y]=1;
                fire.push(b);
            }
        }
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    int t;
    cin>>t;
    while(t--)
    {
        cin>>r>>c;
        A p;
        //memset(maze ,'\0',sizeof(maze));
        for(int i=1;i<=fire.size();i++)
            fire.pop();
        ans=0;
        for(int i=1; i<=r; i++)
            for(int j=1; j<=c; j++)
            {
                cin>>maze[i][j];
                if(maze[i][j]=='J')
                    sx=i,sy=j;
                if(maze[i][j]=='F')
                {
                    p.x=i,p.y=j,p.tim=1;
                    vis[p.x][p.y]=1;
                    fire.push(p);
                }
                Time[i][j]=inf;
            }

        memset(vis,0,sizeof(vis));
        bfs(0);
        ans=inf;
        memset(vis,0,sizeof(vis));
        p.x=sx,p.y=sy,p.tim=1;
        vis[p.x][p.y]=1;
        fire.push(p);
        bfs(1);
        if(ans!=inf)
            cout<<ans<<endl;
        else
            cout<<"IMPOSSIBLE"<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值