续集:广度优先搜索

哈哈哈,上一篇suo了深搜,自然,广搜来了,其实宽度优先搜索能干的事深搜一般也能胜任,广搜常用于找单一的最短路线,它的特点是 “搜到就是最优解”,在空间足够的情况下找最优解可以使用广搜

直接把上次那个题拿来充个数

题目背景
给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。

输入格式
第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点坐标FX,FY。接下来T行,每行为障碍点的坐标。

输出格式
给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标最短步数

给一个简单的数据我们先来分析一下
4 4 3
1 1 4 4
2 2
3 2
3 3

好像不是很直观哈哈,给整个图,就这个亚子叭:
在这里插入图片描述
再给整个编号

在这里插入图片描述

我们先规定,到每个新节点,按右,下,上,左的顺序尝试;那么我们一步一步分析;

先放个流程图,哈哈哈

向右
向右
向下
向右
向下
向下
向右
向下
向下
向下
向下
向右
向右
向右
1
第一步 2
第二步 3
第一步 5
第三步 4
第三步 7
第四步 8
第五步 12
第六步 16
第二步 9
第三步 13
第四步 14
第五步 15

要完成上面的步骤,我们可以这样:

  1. 每一步都尝试能走的所有方向,能走通就往下走
  2. 走过的结点不再走
  3. 只要有一种方式到终点就输出步数

然后我们会发现,和深搜不通的是,广搜走着走着某一步会有很多很多个节点都可以继续往下走,为了保存上一步的节点(们),我们用一个队列来模拟
具体呢就是让头指向上一步的第一个一个节点,然后每处理一个节点就让head++;这样就实现了在进入下一步前,处理的每一个方向都是这一步的,因为广搜本来就是用来找最短路径,所以这样做可以实现
举个例子:
== 蓝色的是top,橘色的是tail==
在这里插入图片描述
看图,,,前两张新增了由第一步第一个节点新产生的两个节点,
然后第一步第二个节点新产生的两个节点
此时当top继续后移就进入下一步继续上面的步骤
可以发现,某一步所走的所有节点都在一起,这就是广搜的效果了

介绍到这里就结束了,其实广搜也可以当作模拟来看,上面的步骤已经给了,下面放代码

#include<stdio.h>
struct node 
{
	int x;
	int y;
	int bs;
}list[10000];//用一个队列来模拟 
int main()
{	
	int i,sd,aa,bb,sx,sy,tx,ty,cc=0;
	int a[100][100]={0},book[100][100]={0},n,m;
	int ex,ey;
	int flag=0;
	int top=0,tail=0; 
	int next[4][2]{{0,1},{1,0},{0,-1},{-1,0}};
	scanf("%d%d%d",&n,&m,&sd);
	scanf("%d%d",&sx,&sy);
	scanf("%d%d",&ex,&ey);
	for(i=0;i<sd;i++)
	{
		scanf("%d%d",&aa,&bb);
		a[aa][bb]=1;
	}
	book[sx][sy]=1;
	//插入第一个节点
	list[tail] .x=sx;
	list[tail].y=sy;
	list[tail].bs=0;
	tail++;
	cc=0;//用来标记是否到达终点; 
	while(tail>top)
	{
	 
		for(i=0;i<4;i++)			//遍历top所指节点的所有下一步
		{
			tx=list[top].x+next[i][0];ty=list[top].y+next[i][1];
			if(tx<1||tx>n||ty<1||ty>m)		//判断边界
			{
				continue;
			}
			if(a[tx][ty]==0&&book[tx][ty]==0)		//判断能否走通
			{
				book[tx][ty]=1;
				list[tail].x=tx;
				list[tail].y=ty;
				list[tail].bs=list[top].bs+1;
				tail++;
				
			}
			if(tx==ex&&ty==ey)			//走到终点了
			{
				cc=1;
				break;
			}
			
		}
		if(cc==1)
		{
			break;
		}
		top++;			//这个节点所有操作结束,top++继续下一个节点
	}
	
	
	printf("%d",list[tail-1].bs);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值