搜索与图论——BFS

文章目录

BFS

宽搜

题目:

给定一个n*m的二维整数数组,用来表示一个迷宫,数组中只包含0或1,其中0表示可以走的路,1表示不可通过的墙壁。
最初,有一个人位于左上角(1, 1)处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。
请问,该人从左上角移动至右下角(n, m)处,至少需要移动多少次。
数据保证(1, 1)处和(n, m)处的数字为0,且一定至少存在一条通路。

在这里插入图片描述

题解

在这里插入图片描述

package Chapter3;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 迷宫
 * @author vccyb
 *
 */
public class P844 {
	static final int N = 110;
	//g地图矩阵 d距离矩阵
	static int[][] g = new int[N][N], d = new int[N][N];
	//q 队列
	static PII[] q = new PII[N*N];
	static int n;
	static int m;
	
	
	static int bfs(){
		int hh=0,tt=-1;
		q[0] = new PII(0,0);//从初始点开始
		//入队了, tt++
		tt++;
		//初始化距离为-1
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				d[i][j] = -1;
			}
		}
		
		//
		d[0][0] = 0; //将初始点的距离初始化为0
		int[] dx = {-1,0,1,0}; //	左		 上		右		下
		int[] dy = {0,1,0,-1}; // {-1,0}	{0,1}	{1,0}	{0,-1}
		
		while(hh<=tt){
			//出队  队列不空,每次出队
			PII t = q[hh++]; //队列后进先出。
			
			for(int i=0;i<4;i++){
				int x = t.getFirst()+dx[i];
				int y = t.getSecond()+dy[i];
				//什么意思?遍历这个点的前后左右
				if(x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1){
					//注意最后一个条件d[x][y] = -1,说明是没有走过的
					//1. 距离跟新+1
					d[x][y] = d[t.getFirst()][t.getSecond()]+1;
					//2. 新的点进队呀
					q[++tt] = new PII(x,y);
				}
			}			
		}
		
		//所有的点进队和出队了
		return d[n-1][m-1]; //返回终点的距离
		
	}
	
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		//输入地图矩阵
		String[] line = br.readLine().split(" ");
		n = Integer.parseInt(line[0]); //地图的行数 n
		m = Integer.parseInt(line[1]); //地图的列数 m
		
	  for(int i=0;i<n;i++){
		  String[] str = br.readLine().split(" ");
          for(int j=0;j<m;j++){
        	  g[i][j]=Integer.parseInt(str[j]);
          }
      }
	  
	  //Test======测试地图是否输入
//	  for(int i=0;i<n;i++){
//		  for(int j=0;j<m;j++){
//			  System.out.print(g[i][j]+" ");
//		  }
//		  System.out.println();
//	  }
	  
	  
	  //.调用bfs咯
	  
	  System.out.println(bfs());
	  br.close();
	  
	}
	
}



//手写pair
//用这个存储两个点的坐标
class PII{
	private int first;
	private int second;
	
	public PII(){
	}
	
	public PII(int first, int second) {
		this.first = first;
		this.second = second;
	}

	public int getFirst() {
		return this.first;
	}

	public int getSecond() {
		return this.second;
	}

	
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值