hdu3085 Nightmare Ⅱ【双向BFS】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085
题意:有一个n*m的地图,有两只狗要见面,M代表第一只狗,G代表第二只狗,Z代表鬼,X代表墙,.表示可以走的地方,每秒钟,鬼先走,鬼每秒钟可以走两步,M狗每秒能走3步,G狗每秒只能走一步,只要两只狗能够互相走到他们之前走过的位置就算见面……现在问你在他们不走到鬼的格子上的情况下而完成目标的最小时间,如果能就输出最小时间,如果不能就输出-1
解析:这个应该能很好理解双向BFS,和普通BFS没啥大的区别,判断是否会走到鬼的格子上,只需要判断和鬼的曼哈顿距离即可

#include 
using namespace std;
struct node
{
    int x,y;
    node() {}
    node(int _x,int _y)
    {
        x = _x;
        y = _y;
    }
}ghost[1005];
char a[1005][1005];
int vis[2][1005][1005];
int dx[] = {0,1,-1,0};
int dy[] = {1,0,0,-1};
int n,m,cnt;
queueq[2];
bool check(int x,int y,int time)
{
    for(int i=0;iint tmp = abs(x-ghost[i].x)+abs(y-ghost[i].y);
        if(tmp<=2*time)
            return false;
    }
    return true;
}
bool bfs(int type,int time)
{
    int res = q[type].size();
    while(res--)
    {
        node now = q[type].front();
        q[type].pop();
        if(!check(now.x,now.y,time))
            continue;
        for(int i=0;i<4;i++)
        {
            int tx = now.x+dx[i];
            int ty = now.y+dy[i];
            if(tx<0 || tx>=n  || ty<0 || ty>=m)
                continue;
            if(vis[type][tx][ty] || a[tx][ty]=='X')
                continue;
            if(check(tx,ty,time))
            {
                if(vis[type^1][tx][ty])
                    return true;
                vis[type][tx][ty] = 1;
                q[type].push(node(tx,ty));
            }
        }
    }
    return false;
}
int slove(int x1,int y1,int x2,int y2)
{
    while(!q[0].empty()) q[0].pop();
    while(!q[1].empty()) q[1].pop();
    memset(vis,0,sizeof(vis));
    q[0].push(node(x1,y1));
    q[1].push(node(x2,y2));
    vis[0][x1][y1] = 1;
    vis[1][x2][y2] = 1;
    int time = 0;
    while(!q[0].empty() || !q[1].empty())
    {
        time++;
        if(bfs(0,time))
            return time;
        if(bfs(0,time))
            return time;
        if(bfs(0,time))
            return time;
        if(bfs(1,time))
            return time;
    }
    return -1;
}
int main(void)
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        cnt = 0;
        scanf("%d %d",&n,&m);
        int x1,y1,x2,y2;
        for(int i=0;i"%s",a[i]);
            for(int j=0;j<m;j++)
            {
                if(a[i][j]=='Z')
                    ghost[cnt++]= node(i,j);
                if(a[i][j]=='M')
                    x1 = i,y1 = j;
                if(a[i][j]=='G')
                    x2 = i,y2 = j;
            }
        }
        printf("%d\n",slove(x1,y1,x2,y2));
    }
    return 0;
}

你可能感兴趣的:(ACM,OnlineJudge,HDU,ACM,BFS&DFS)