[hdu 3085]双向bfs

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085

卡了很长时间的一个题终于过了,通过http://blog.csdn.net/u013899738/article/details/48003491学习到了双向bfs的正确姿势。

卡了很长时间char数组需要初始化为0。

#include<bits/stdc++.h>
using namespace std;

const int maxn=805;
const int INF=0x3f3f3f3f;
char s[maxn][maxn];
int ghost[maxn][maxn];
int bx,by,gx,gy;

void getxy(int n,int m)
{
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++)
            if (s[i][j]=='M') bx=i,by=j;
            else if (s[i][j]=='G') gx=i,gy=j;
}

bool vis[2][maxn][maxn];
queue<int> q[2];
const int fx[]={0,0,1,-1};
const int fy[]={1,-1,0,0};

bool walk(int w,int st)
{
    int th=q[w].size();
    while (th--)
    {
        int x=q[w].front()/1000;
        int y=q[w].front()%1000;
        q[w].pop();
        if (ghost[x][y]<=st) continue;
        for (int i=0;i<4;i++)
        {
            int xx=x+fx[i];
            int yy=y+fy[i];
            if (s[xx][yy]!=0 && s[xx][yy]!='X' && ghost[xx][yy]>=st+1 && !vis[w][xx][yy])
            {
                if (vis[w^1][xx][yy]) return true;
                q[w].push(xx*1000+yy);
                vis[w][xx][yy]=true;
            }
        }
    }
    return false;
}

int bfs()
{
    memset(vis,false,sizeof(vis));
    for (int i=0;i<2;i++) while (!q[i].empty()) q[i].pop();
    q[0].push(bx*1000+by);
    vis[0][bx][by]=true;
    q[1].push(gx*1000+gy);
    vis[1][gx][gy]=true;
    int st=0;
    while (!q[0].empty() || !q[1].empty())
    {
        st++;
        if (walk(0,st)) return st;
        if (walk(0,st)) return st;
        if (walk(0,st)) return st;
        if (walk(1,st)) return st;
    }
    return -1;
}

int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        memset(s,0,sizeof(s));
        for (int i=1;i<=n;i++) scanf("%s",s[i]+1);
        memset(ghost,INF,sizeof(ghost));
        for (int i=1;i<=n;i++)
            for (int j=1;j<=m;j++)
                if (s[i][j]=='Z')
                {
                    for (int _i=1;_i<=n;_i++)
                        for (int _j=1;_j<=m;_j++)
                            ghost[_i][_j]=min(ghost[_i][_j],(abs(i-_i)+abs(j-_j)+1)/2);
                    s[i][j]='X';
                }
        getxy(n,m);
        printf("%d
",bfs());
    }
    return 0;
}
原文地址:https://www.cnblogs.com/acmsong/p/7493721.html