Layer by layer -- breadth first search

Posted by jehardesty on Sat, 05 Mar 2022 09:04:33 +0100

Breadth first search, also known as breadth first search. It is similar to depth first search, which starts from a certain state to explore all reachable states.

The difference from depth first search is the order of search. Width first search always searches the state close to the initial state first. In other words, it searches according to the order of start state → all states that can be reached with only one transition → all states that can be reached with only two transitions → ··································································. For the same state, the width first search only goes through once, so the complexity is O (number of States) × Transfer mode).

Depth first search (implicitly) uses stacks for computation, while width first search uses queues. When searching, first add the initial state to the queue, then continuously take out the state from the front end of the queue, and add the unreachable part of the state that can be transferred from the state to the queue. Repeat until the queue is empty or the solution to the problem is found. By observing this queue, we can know that all States are traversed in the order from near to far from the initial state.

Here is a classic maze example:

Given a size of N × M's maze. The maze is composed of channels and walls. Each step can move to the adjacent upper, lower, left and right channels. Request the minimum number of steps required from the start point to the end point. Please note that this question assumes that you can move from the starting point to the end point. (N,M ≤ 100) ('#', '.','s', and 'g' represent wall, channel, starting point and ending point respectively)

Input:

10 10

#S######.#
......#..#
.#.##.##.#
.#........
##.##.####
....#....#
.#######.#
....#.....
.####.###.
....#...G#

Output:

22

code:

 1 #include<iostream>
 2 #include<queue>
 3 using namespace std;
 4 const int INF = 100000000, maxn = 105;
 5 typedef pair<int, int> P;//Structure can be used
 6 char maze[maxn][maxn];
 7 int n, m, sx, sy, gx, gy,d[maxn][maxn];//An array of the shortest distances to each location
 8 int dx[4] = { 1,0,-1,0 }, dy[4]= { 0,1,0,-1 };//4 Vector moving in two directions
 9 int bfs()//Seek obedience(sx,sy)reach(gx,gy)The shortest distance, if unreachable, is INF
10 {
11     queue<P> que; 
12     for (int i = 0; i < n; i++)
13         for (int j = 0; j < m; j++)
14             d[i][j] = INF;//All locations are initialized to INF
15     que.push(P(sx, sy));//Add the starting point to the queue
16     d[sx][sy] = 0;//And set the distance of this location to 0
17     while (que.size())//Keep cycling until the length of the queue is 0
18     {
19         P p = que.front();// Take the element from the first segment of the queue
20         que.pop();//Remove the element from the queue after extraction
21         if (p.first == gx&&p.second == gy)
22             break;
23         for (int i = 0; i < 4; i++)//Cycle in four directions
24         {
25             int nx = p.first + dx[i],ny = p.second + dy[i];//The moved position is marked as(nx,ny)
26             if (0 <= nx&&nx < n && 0 <= ny&&ny < m&&maze[nx][ny] != '#'&&d[nx][ny] == INF)//Judge whether it can be moved and accessed(Namely d[nx][ny]!=INF)
27             {
28                 que.push(P(nx, ny));//Can be moved and added to the queue
29                 d[nx][ny] = d[p.first][p.second] + 1;//The distance to this location is to p Distance+1
30             }
31         }
32     }
33     return d[gx][gy];
34 }
35 int main()
36 {
37     cin >> n >> m;
38     sx = 0, sy = 1, gx = 9, gy = 8;//Start and end coordinates
39     for (int i = 0; i < n; i++)
40         for (int j = 0; j < m; j++)
41             cin >> maze[i][j];
42     cout << bfs() << endl;
43     return 0;
44 }

Another similar example:

One day, xiaoha went to play the maze. But xiaoha, who had a bad sense of direction, soon got lost. When Xiao hum learned that, he immediately went to rescue the helpless Xiao ha. Of course, Xiao hum came prepared. He has figured out the maze map. Now Xiao hum wants to rescue Xiao HA as soon as possible. The problem begins
The maze consists of n rows and m columns of cells, each of which is either an open space or an obstacle. Your task is to help xiaohum find the shortest path from the beginning of the maze to xiaoha's location. Pay attention to the obstacles. Of course, you can't go outside the maze. Both n and m are less than or equal to 100.


Input format:

The first line has two numbers n, M. N represents the row of the maze and M represents the column of the maze. Next, n rows and m columns are mazes, 0 represents open space and 1 represents obstacles. There are four numbers in the last line, and the first two numbers are the x and y coordinates of the maze entrance. The last two are the x and y coordinates of xiaoha.
Output format:

An integer represents the shortest number of steps from small hum to small ha. If you can't save xiaoha, output No Way!

Example 1:

Input:
5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3
Output:
7
code:
#include <bits/stdc++.h>
using namespace std;
 
struct note{//Create a structure 
    int x;//Storage think x coordinate 
    int y;//deposit y coordinate 
    int s;//Number of steps 
};
 
int main()
{
    struct note p[10001];//Create a queue 
    int a[101][101]={0},book[101][101]={0};//a deposit, book Mark points that have passed 
    int n,m,i,j,flag=0,x0,y0,endx,endy,tx,ty;
    //x0,y0 Store the coordinates of the initial position, flag Tag variables, endx,endy Storage position coordinates of xiaoha 
    int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//There is a two-dimensional array representing the direction 
    int tail=1,head=1;//Initialize queue 
    
    cin>>n>>m;
    
    for(i=1;i<=n;i++)
    for(j=1;j<=m;j++)
        cin>>a[i][j];
     cin>>x0>>y0>>endx>>endy;
    
    //initialization 
    p[tail].x=x0;
    p[tail].y=y0;
    p[tail].s=0;
    
    tail++;
    book[x0][y0]=1;
    while(head<tail)
    {
        for(i=0;i<4;i++)//Explore each direction separately 
        {
            tx=p[head].x+next[i][0];
            ty=p[head].y+next[i][1];
            
            if(tx<1||tx>n||ty<1||ty>m)//Judge boundary 
                continue;
                
            if(book[tx][ty]==0&&a[tx][ty]==0)//If you haven't walked, you can explore without obstacles 
            {
                book[tx][ty]=1;//sign 
                p[tail].x=tx;//Put in queue 
                p[tail].y=ty;
                p[tail].s=p[head].s+1;//Record steps 
                tail++;
            }
            
            if(tx==endx&&ty==endy)//If the target point is reached, mark and exit the loop 
            {
                flag=1;
                break;
            }
        }
        
        if(flag==1) break;
        head++;//When a point expansion ends, head++Then the following points can be extended
    }
    
    if(flag==1)//Judge whether the rescue is successful and output data 
    {
        cout<<p[tail-1].s;
    }
    else
        cout<<"No Way!"<<endl;
    return 0;
} 

Test website: https://www.acoj.com/problems/12032

Like deep search, wide search will generate all traversable States, so it is also possible to use width first search when processing all States. However, recursive functions can be written very briefly, and the management of state is simpler, so in most cases, they are implemented by deep search. On the contrary, when finding the shortest path, the depth first search needs to experience the same state repeatedly, so it is better to use the width first search at this time.