Quick Start for BFS Shortest Path Problem Novices

A large part of the maze problems we encountered can be solved with BFS. Solving these kinds of problems can greatly improve your abilities and skills, and I will try to help you understand how to use BFS to solve them. This article is based on a simple example


Example:
In the first line, two integers n and m are the length and width of the maze.
The next n lines, each of the m numbers is one of 0 or 1. 0 means this grid can pass, 1 means it cannot. Suppose you are now at the maze coordinate (1,1), which is the upper left corner, and the exit of the maze is at (n,m). Each time you move, you can only move in four directions, up, down, left, and right, to another passable grid, and each move counts as one step. The data guarantees that (1,1), (n,m) can pass.
Output format
  The first line is the minimum number of steps required K.
  The second line contains K characters, each character ∈ {U, D, L, R}, respectively representing up, down, left and right. If there are multiple shortest paths of the same length, choose the one with the smallest lexicographical order under this representation.
 Input
Sample 1:
3 3
0 0 1
1 0 0
1 1 0

Input Sample 2:
3 3
0 0 0
0 0 0
0 0 0
Sample Output
Output Sample 1:
4
RDRD

Output Sample 2:
4
DDRR


BFS, a blind search method, aims to systematically expand and examine all nodes in the graph to find results. In other words, it does not consider the possible location of the result and searches the entire graph thoroughly until it finds a result.
Fake code

queue.add(起点);
while(队列不为空){
    取出队首点
    if(如果为终点)
        结束
    //不为终点,继续向下走
    for(方向)
        ...
}

Paste the example code below


public class test3 {

    static int[][] one = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };//上下左右移动坐标的变化
    static String[] nextpath = { "U", "D", "L", "R" };//上下左右移动的表示

    static class point {
   
   //点类记录当前坐标,步数,路径
        int x, y, step;//step表示从出发到当前点经过几步
        String path;//path表示从出发到当前点经过路径

        public point(int x, int y, int step, String path) {
            this.x = x;
            this.y = y;
            this.step = step;
            this.path = path;
        }

    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int[][] a = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                a[i][j] = in.nextInt();
            }
        }
        bfs(a, n, m);
    }

    //按字典序较小选择路径
    public static boolean judge(String A, String B) {
        char[] arrayA = A.toCharArray();
        char[] arrayB = B.toCharArray();
        for (int i = 0, len = A.length(); i < len; i++) {
            if (arrayA[i] < arrayB[i])
                return false;
        }
        return true;
    }

    //判断点是否出界或被访问过
    public static boolean check(int[][] matrix, point a) {
        int n = matrix.length - 1, m = matrix[0].length - 1;
        if (a.x < 0 || a.x > n || a.y < 0 || a.y > m || matrix[a.x][a.y] == 1)
            return false;
        return true;
    }

    //搜索
    static void bfs(int[][] a, int n, int m) {
        ArrayList<point> list = new ArrayList<point>();
        list.add(new point(0, 0, 0, ""));//向队列中加入第一个点
        int minStep = Integer.MAX_VALUE;//最小步数
        String minPath = "";//最短路径
        while (list.size() != 0) {
            point b = list.get(0);//当队列中有点时,取出点比较是否为终点
            list.remove(0);//删除该点
            if (b.x == n - 1 && b.y == m - 1) {
                if (minStep > b.step) {
                    minStep = b.step;
                    minPath = b.path;
                } else if (minStep == b.step) {
                    if (judge(minPath, b.path)) {
                        minPath = b.path;
                    }
                }
                continue;

            }
            //如果不是终点,依次尝试访问上下左右,并加入队列继续循环
            for (int i = 0; i < 4; i++) {
                int x = b.x + one[i][0];
                int y = b.y + one[i][1];
                int step = b.step + 1;
                String path = b.path + nextpath[i];
                point p = new point(x, y, step, path);
                if (check(a, p)) {
                    list.add(p);
                    a[x][y] = 1;
                }
            }
        }
        System.out.println(minPath + "\n" + minStep);//循环结束输出最短步数及路径
        return;
    }

}

operation result

3 3
0 1 0
0 1 0
0 0 0
DDRR
4

If there is no channel, Integer.Max_Value will be output

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=324036898&siteId=291194637