• [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;
    }
  • 相关阅读:
    Fibonacci(斐波那契)数列方法整理
    java数组可遍历但是不能作为Iterable参数传递
    欧几里得算法的证明
    List<? extends Pet>中问号的解释
    P1387 最大正方形
    P1313 计算系数
    P1049 装箱问题
    乘积最大
    P1091 合唱队形
    bsgs
  • 原文地址:https://www.cnblogs.com/acmsong/p/7493721.html
Copyright © 2020-2023  润新知