Loading

经典BFS-走迷宫

一、问题分析

原题链接:https://www.acwing.com/problem/content/846/

image-20220302181219647

宽搜的优势:可以搜到最短路

记录每一个能走的位置对于起点的距离,这样可以很容易计算到达终点的最短路。(针对所有边权重都是一样的题)

image-20220331164348082

二、代码实现

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

// 宽搜需要使用队列,定义一个适合该题的类,作为队列的泛型。
class Node {
	int x;
	int y;

	public Node(int x, int y) {
		this.x = x;
		this.y = y;
	}

}

public class Main {
	static int N = 110;
	static int n;
	static int m;
	// 保存地图情况
	static int[][] g = new int[N][N];
	// 保存每一步对于初始位置的距离
	static int[][] path = new int[N][N];
	// 因为要计算对于当前位置的四周位置,不使用多个if,使用偏移量
	static int[] xx = { 1, 0, -1, 0 };
	static int[] yy = { 0, -1, 0, 1 };

	static void bfs() {
		// 维护队列,用于保存路径
		// 队列要频繁地操作队头队尾,用LinkedList效率更高。
		Queue<Node> queue = new LinkedList<>();
		// 将起点添加进队列
		queue.offer(new Node(0, 0));

		while (!queue.isEmpty()) {
			Node node = queue.poll();
			// 到达边界
			if (node.x == n - 1 && node.y == m - 1) {
				break;
			}

			// 找路,四个方向
			for (int i = 0; i < 4; i++) {
				int newx = node.x + xx[i];
				int newy = node.y + yy[i];
				// 要先判断新位置是否超出边界,再判断新位置是否能走和是否走过(顺序反过来可能会出现数组越界)
				if (newx >= 0 && newx < n && newy >= 0 && newy < m && g[newx][newy] == 0 && path[newx][newy] == 0) {
					// 将新位置添加进队列
					queue.offer(new Node(newx, newy));
					// 新位置比原位置离出发位置的距离 +1
					path[newx][newy] = path[node.x][node.y] + 1;
				}
			}
		}

		System.out.println(path[n - 1][m - 1]);

	}

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

		bfs();
	}
}
posted @ 2022-03-31 16:48  KledKled  阅读(56)  评论(0编辑  收藏  举报