• POJ 1915-Knight Moves (单向BFS && 双向BFS 比)


    主题链接:Knight Moves


    题意:8个方向的 马跳式走法 ,已知起点 和终点,求最短路

    研究了一下双向BFS,不是非常难,和普通的BFS一样。双向BFS只是是从 起点和终点同一时候開始搜索,可降低搜索时间

    当两条搜索路线相遇时,结束。

    貌似有一年百度的招聘 笔试,就是双向BFS。

    。。。


    以下,比較一下BFS 和 双向BFS的用时。


    BFS


    STL的queue可能会浪费一点时间


    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    const int N = 310;
    using namespace std;
    int mapp[N][N];
    bool vis[N][N];
    struct node{
        int x,y,ans;
    };
    int n;
    int mv[8][2] = {{1,2},{1,-2},{2,1},{2,-1},{-2,1},{-2,-1},{-1,2},{-1,-2}};
    void BFS(int sx,int sy,int ex,int ey)
    {
        queue<node>q;
        node t,f;
        memset(vis,0,sizeof(vis));
        f.x = sx; f.y = sy; f.ans = 0;
        vis[sx][sy] = true;
        q.push(f);
        while(!q.empty())
        {
            t = q.front();
            q.pop();
            if(t.x==ex && t.y==ey)
            {
                printf("%d
    ",t.ans);
                return ;
            }
            
            for(int i = 0;i<8;i++)
            {
                f.x = t.x + mv[i][0];
                f.y = t.y + mv[i][1];
                if(!vis[f.x][f.y]&& 0<=f.x && f.x <n && 0<=f.y && f.y<n)
                {
                    f.ans = t.ans + 1;
                    q.push(f);
                    vis[f.x][f.y] = true;
                }
            }
        }
    }
    int main()
    {
        int t,sx,sy,ex,ey;
        std::ios::sync_with_stdio(false);
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            scanf("%d%d",&sx,&sy);
            scanf("%d%d",&ex,&ey);
            BFS(sx,sy,ex,ey);
        }
        return 0;
    }

    双向BFS


    时间差的不是非常大,可是理论上,时间复杂度会降低若干倍。假设数据大的话,时间差会非常明显


    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    const int N = 310;
    using namespace std;
    int mapp[N][N];
    int vis[N][N];
    struct node{
        int x,y;
    };
    int n;
    int mv[8][2] = {{1,2},{1,-2},{2,1},{2,-1},{-2,1},{-2,-1},{-1,2},{-1,-2}};
    int dis[N][N];
    void BFS(int sx,int sy,int ex,int ey)
    {
        if(sx==ex && sy == ey)
        {
            printf("0
    ");
            return ;
        }
        queue<node>q;
        node t,f;
        memset(vis,0,sizeof(vis));
        memset(dis,0,sizeof(dis));
        f.x = sx; f.y = sy;
        t.x = ex; t.y = ey;
        vis[sx][sy] = 1; //从起点開始搜索的路线  标记为1
        vis[ex][ey] = 2; //从终点開始搜索的路线  标记为2
        q.push(f);
        q.push(t);
        while(!q.empty())
        {
            t = q.front();
            q.pop();
            for(int i = 0;i<8;i++)
            {
                f.x = t.x + mv[i][0];
                f.y = t.y + mv[i][1];
                if(0<=f.x && f.x <n && 0<=f.y && f.y<n)
                {
                    if(!vis[f.x][f.y])
                    {
                    dis[f.x][f.y] = dis[t.x][t.y] + 1;
                    q.push(f);
                    vis[f.x][f.y] = vis[t.x][t.y];
                    }
                    else if(vis[f.x][f.y]!=vis[t.x][t.y]) //两者相遇
                    {
                        printf("%d
    ",dis[f.x][f.y]+dis[t.x][t.y] + 1); //会漏掉相遇的那个点,所以要加1
                        return ;
                    }
    
                }
            }
        }
    }
    int main()
    {
        int t,sx,sy,ex,ey;
        std::ios::sync_with_stdio(false);
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            scanf("%d%d",&sx,&sy);
            scanf("%d%d",&ex,&ey);
            BFS(sx,sy,ex,ey);
        }
        return 0;
    }
    



    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    python的模块future用法实例解析
    strcmp函数和memcmp函数的用法区别及联系
    esp8266 smartconfig-智能配网分析和使用及注意事项
    ubuntu 18.04 安装并配置adb
    Markdown的常用方法总结
    mac下使用minicom几个注意事项
    最强Linux shell工具Oh My Zsh 指南
    ESP8266源码分析--打印的基本用法
    atom 在Ubuntu 18.04 上安装及基本使用
    ubuntu 查看端口被占用并删除端口
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4869408.html
Copyright © 2020-2023  润新知