搜索(bfs)

Posted chen-1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搜索(bfs)相关的知识,希望对你有一定的参考价值。

之前,我简略的讲了讲dfs相关的事(见https://www.cnblogs.com/chen-1/p/12328832.html)。

 

接下来,我要简单说一下有关另一种搜索方式——广搜(广度优先搜索),也就是bfs。但首先要明白,bfs与dfs有什么区别。

很明显,它们的搜索方式不同。顾名思义,广搜,是以“广”为搜索顺序的,也就是搜索到一个结点时,会将所有与之相连的

结点都遍历一遍,所以用一个递归的方式来bfs一个图就不太对了。于是用一个队列来储存待遍历的点,可以说是一个等待区,

依次将队列中的点取出并删除,然后将该点所连且未曾入过队的结点都都放入队列尾部,直到队列变空,这样就能实现对全图

的遍历。

 

接下来,可以看一下广搜遍历过程:(假设默认右手法则)

技术图片

 

技术图片

技术图片

技术图片

技术图片

完美完成遍历!

注:广搜适合以其中一个点为起点,求到很多点的路径

 

然后就是广搜经典例题:

https://www.luogu.com.cn/problem/P1443马的遍历

解析:就套用广搜模板,并向8个方向枚举即可。

while(tail>head)
{
    //分别枚举8个方向 
    if(q[head].x+2<=n && q[head].y+1<=m && q[head].x+2>=1 && q[head].y+1>=1 && !flag[q[head].x+2][q[head].y+1])
    {
        //放入队尾 
        q[tail].x=q[head].x+2;
        q[tail].y=q[head].y+1;
        q[tail].num=q[head].num+1;
        flag[q[head].x+2][q[head].y+1]=1;
        tail++;
    }
    if(q[head].x+1<=n && q[head].y+2<=m && q[head].x+1>=1 && q[head].y+2>=1 && !flag[q[head].x+1][q[head].y+2])
    {
        //放入队尾
        q[tail].x=q[head].x+1;
        q[tail].y=q[head].y+2;
        q[tail].num=q[head].num+1;
        flag[q[head].x+1][q[head].y+2]=1;
        tail++;
    }
    if(q[head].x-2<=n && q[head].y-1<=m && q[head].x-2>=1 && q[head].y-1>=1 && !flag[q[head].x-2][q[head].y-1])
    {
        //放入队尾
        q[tail].x=q[head].x-2;
        q[tail].y=q[head].y-1;
        q[tail].num=q[head].num+1;
        flag[q[head].x-2][q[head].y-1]=1;
        tail++;
    }
    if(q[head].x-1<=n && q[head].y-2<=m && q[head].x-1>=1 && q[head].y-2>=1 && !flag[q[head].x-1][q[head].y-2])
    {
        //放入队尾
        q[tail].x=q[head].x-1;
        q[tail].y=q[head].y-2;
        q[tail].num=q[head].num+1;
        flag[q[head].x-1][q[head].y-2]=1;
        tail++;
    }
    if(q[head].x-2<=n && q[head].y+1<=m && q[head].x-2>=1 && q[head].y+1>=1 && !flag[q[head].x-2][q[head].y+1])
    {
        //放入队尾
        q[tail].x=q[head].x-2;
        q[tail].y=q[head].y+1;
        q[tail].num=q[head].num+1;
        flag[q[head].x-2][q[head].y+1]=1;
        tail++;
    }
    if(q[head].x-1<=n && q[head].y+2<=m && q[head].x-1>=1 && q[head].y+2>=1 && !flag[q[head].x-1][q[head].y+2])
    {
        //放入队尾
        q[tail].x=q[head].x-1;
        q[tail].y=q[head].y+2;
        q[tail].num=q[head].num+1;
        flag[q[head].x-1][q[head].y+2]=1;
        tail++;
    }
    if(q[head].x+2<=n && q[head].y-1<=m && q[head].x+2>=1 && q[head].y-1>=1 && !flag[q[head].x+2][q[head].y-1])
    {
        //放入队尾
        q[tail].x=q[head].x+2;
        q[tail].y=q[head].y-1;
        q[tail].num=q[head].num+1;
        flag[q[head].x-2][q[head].y+1]=1;
        tail++;
    }
    if(q[head].x+1<=n && q[head].y-2<=m && q[head].x+1>=1 && q[head].y-2>=1 && !flag[q[head].x+1][q[head].y-2])
    {
        //放入队尾
        q[tail].x=q[head].x+1;
        q[tail].y=q[head].y-2;
        q[tail].num=q[head].num+1;
        flag[q[head].x+1][q[head].y-2]=1;
        tail++;
    }
    //弹出队首 
    head++;
}

 

完整代码:

#include<bits/stdc++.h>
using namespace std;
struct Horse
{
    int x,y;
    int num;    
}q[500*500];
bool flag[501][501];
int head,tail;
int n,m,st1,st2;
int ans[500][500];
int main()
{
    memset(ans,-1,sizeof(ans));
    scanf("%d%d%d%d",&n,&m,&st1,&st2);
    q[1].x=st1,q[1].y=st2,q[1].num=0;
    flag[q[1].x][q[1].y]=1;
    tail=2,head=1;
    while(tail>head)
    {
        if(q[head].x+2<=n && q[head].y+1<=m && q[head].x+2>=1 && q[head].y+1>=1 && !flag[q[head].x+2][q[head].y+1])
        {
            q[tail].x=q[head].x+2;
            q[tail].y=q[head].y+1;
            q[tail].num=q[head].num+1;
            flag[q[head].x+2][q[head].y+1]=1;
            tail++;
        }
        if(q[head].x+1<=n && q[head].y+2<=m && q[head].x+1>=1 && q[head].y+2>=1 && !flag[q[head].x+1][q[head].y+2])
        {
            q[tail].x=q[head].x+1;
            q[tail].y=q[head].y+2;
            q[tail].num=q[head].num+1;
            flag[q[head].x+1][q[head].y+2]=1;
            tail++;
        }
        
        
        if(q[head].x-2<=n && q[head].y-1<=m && q[head].x-2>=1 && q[head].y-1>=1 && !flag[q[head].x-2][q[head].y-1])
        {
            q[tail].x=q[head].x-2;
            q[tail].y=q[head].y-1;
            q[tail].num=q[head].num+1;
            flag[q[head].x-2][q[head].y-1]=1;
            tail++;
        }
        if(q[head].x-1<=n && q[head].y-2<=m && q[head].x-1>=1 && q[head].y-2>=1 && !flag[q[head].x-1][q[head].y-2])
        {
            q[tail].x=q[head].x-1;
            q[tail].y=q[head].y-2;
            q[tail].num=q[head].num+1;
            flag[q[head].x-1][q[head].y-2]=1;
            tail++;
        }
        
        
        if(q[head].x-2<=n && q[head].y+1<=m && q[head].x-2>=1 && q[head].y+1>=1 && !flag[q[head].x-2][q[head].y+1])
        {
            q[tail].x=q[head].x-2;
            q[tail].y=q[head].y+1;
            q[tail].num=q[head].num+1;
            flag[q[head].x-2][q[head].y+1]=1;
            tail++;
        }
        if(q[head].x-1<=n && q[head].y+2<=m && q[head].x-1>=1 && q[head].y+2>=1 && !flag[q[head].x-1][q[head].y+2])
        {
            q[tail].x=q[head].x-1;
            q[tail].y=q[head].y+2;
            q[tail].num=q[head].num+1;
            flag[q[head].x-1][q[head].y+2]=1;
            tail++;
        }
        
        
        if(q[head].x+2<=n && q[head].y-1<=m && q[head].x+2>=1 && q[head].y-1>=1 && !flag[q[head].x+2][q[head].y-1])
        {
            q[tail].x=q[head].x+2;
            q[tail].y=q[head].y-1;
            q[tail].num=q[head].num+1;
            flag[q[head].x-2][q[head].y+1]=1;
            tail++;
        }
        if(q[head].x+1<=n && q[head].y-2<=m && q[head].x+1>=1 && q[head].y-2>=1 && !flag[q[head].x+1][q[head].y-2])
        {
            q[tail].x=q[head].x+1;
            q[tail].y=q[head].y-2;
            q[tail].num=q[head].num+1;
            flag[q[head].x+1][q[head].y-2]=1;
            tail++;
        }
        head++;
    }
    for(int i=1;i<=tail;i++)
    {
        if(ans[q[i].x][q[i].y]>0) ans[q[i].x][q[i].y]=min(q[i].num,ans[q[i].x][q[i].y]);
        else ans[q[i].x][q[i].y]=q[i].num;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            printf("%-5d",ans[i][j]);
        }
        printf("
");
    }
    return 0;
}

 

最后,还是照例推荐几道较难的题

https://loj.ac/problems/search?keyword=1.4

以上是关于搜索(bfs)的主要内容,如果未能解决你的问题,请参考以下文章

在Prolog中使用广度优先搜索(BFS)解决食人族/传教士?

广度优先搜索(BFS)

通过迷宫问题简单学习DFS和BFS算法

通过迷宫问题简单学习DFS和BFS算法

通过迷宫问题简单学习DFS和BFS算法

广度优先搜索(BFS)的一个(重要!)细节。