13.广度优先搜索

news2024/11/16 8:18:49

一、算法内容

1.简介

广度优先搜索BFS(Breadth First Search)按照广度优先的方式进行搜索,可以理解为“尝试所有下一步可能”地穷举所有可行的方案,并不断尝试,直到找到一种情况满足问题问题的要求。

BFS从起点开始,优先搜索离起点最近的点,然后由这个最近的点扩展其他稍近的点,这样一层一层的扩展,就像水波扩散一样。故而可以把BFS当成并行计算的一种模拟。

广度优先搜索可以用队列实现,而且几乎都是用队列实现,所以要学会广度优先搜索,首先必须要学会队列。而在BFS中,可能不止使用基本的队列,优先队列和双端队列也可能被使用并用来优化BFS。在后续BFS优化的学习中,我们会提到这些知识。

2.与DFS的对比

与深度优先搜索不同的是,广度优先搜索会先将与起始点距离较近的点搜索完毕,再继续搜索较远的点,而深搜却是沿着一个分支搜到最后。故而当需要选择搜索方式的时候,评估答案可能出现的位置将作为一个可靠的依据。如果答案出现在浅层,那么使用BFS更好;如果答案出现在深层,那么使用DFS更好。

如果将搜索的过程画出来,那么它就像一棵树,每一个结点都有相应的状态,分别代表了一种可能性。之所以叫做广度优先,是因为我们总是将当前层拓展完之后才会进入树的下一层。

在这里插入图片描述

3.队列使用的基本过程

BFS需要借助队列来实现:

  1. 初始的时候把起始点放到队列中,并标记起点访问。
  2. 如果队列不为空,从队列中取出一个元素u,否则算法结束。
  3. 访问和u相连的所有点v,如果v没有被访问,把v入队,并标记已经访问。
  4. 重复执行步骤 2。

二、算法实现

1.算法模板

参数 bfs(变量)
{
	起点设置
	将起点入队
	如果队列不为空:
    	取出队首:
        枚举此时下一步所有的可能性:
            得到下一步的状态
            如果下一步是合法的/更优的:
            	将下一步的状态入队
    返回答案
}

2.实例剖析:T1770 洪水

(1)限定条件

  • 水不能流出矩阵,即任何时候,当前坐标 ( x , y ) (x,y) (x,y)满足 1 ≤ x ≤ n , 1 ≤ y ≤ m 1\leq x\leq n,1\leq y\leq m 1xn,1ym
  • 水往低处流,即水要向高度相同或者更低的地方扩散。
  • 注意不要原路返回,否则将进入无限循环。

(2)更新状态

若当前坐标为 ( x , y ) (x,y) (x,y),则下一步的坐标即为 ( x − 1 , y ) , ( x + 1 , y ) , ( x , y − 1 ) , ( x , y + 1 ) (x-1,y),(x+1,y),(x,y-1),(x,y+1) (x1,y),(x+1,y),(x,y1),(x,y+1)。我们需要在限定条件内走到这些位置。

而我们的状态分为两部分构成,结合这两个状态我们就可以唯一标识一种情况:

  • 第一部分:显然我们当前的坐标是我们的一个状态。
  • 第二部分:为了保证我们不要进入循环,我们需要标记我们的来路,这就是第二部分的状态。

(3)正解代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib> 
#include <cmath>
#include <queue>

using namespace std;
typedef long long ll;
struct node
{
	ll x,y;
};
ll dx[4]={0,0,1,-1},dy[4]={-1,1,0,0};
ll mp[1010][1010];
bool vis[1010][1010];
ll n,m,ans;
void bfs(ll sx,ll sy)
{
    queue<node> q;
    q.push(node{sx,sy});
    vis[sx][sy]=true;
    ans++;
    while(!q.empty())
	{
		node now=q.front();
		q.pop();
		for(ll i=0;i<4;i++)
		{
			node New;
			New.x=now.x+dx[i];
			New.y=now.y+dy[i];
			if(New.x>=1 && New.x<=n && New.y>=1 && New.y<=m && !vis[New.x][New.y] && mp[New.x][New.y]<=mp[now.x][now.y])
			{
				vis[New.x][New.y]=true;
				ans++;
				q.push(New);
			}
		}
	}
}
int main()
{
    cin>>n>>m;
    for(ll i=1;i<=n;i++)
    	for(ll j=1;j<=m;j++)
    		cin>>mp[i][j];
    ll sx,sy;
    cin>>sx>>sy;
    bfs(sx,sy);
    cout<<n*m-ans<<endl;
    
    return 0;
} 

三、作业

1.橙题

P1162 填涂颜色

T1770 洪水

2.黄题

P1443 马的遍历

P1649 [USACO07OCT]Obstacle Course S

P4017 最大食物链计数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/431375.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言——学生信息管理系统(数组)

文章目录一、前言二、目的三、框架1.菜单1.1主菜单1.2子菜单2.流程图2.1总流程图2.2开始流程图2.3增加学生信息流程图2.4.删除学生信息流程图2.5修改学生信息流程图2.6查询学生信息流程图2.7对学生信息排序流程图3.思路四、代码五、演示视频一、前言 因为最近是在赶进度总结&a…

无人驾驶--工控机安装autoware

时隔好久&#xff0c;又来写文章了&#xff0c;这次有高人指点&#xff0c;要系统的学习一下无人驾驶了。 使用的是易咖的底盘车&#xff0c;工控机是米文动力Apex Xavier II&#xff0c;基于autoware框架 首先是在工控机上安装autoware&#xff0c;工控是ubuntu18环境。 参…

Python入门教程+项目实战-9.2节: 字符串的操作符

目录 9.2.1 字符串常用操作符 9.2.2 操作符&#xff1a;拼接字符串 9.2.3 *操作符&#xff1a;字符串的乘法 9.2.4 []操作符&#xff1a;索引访问 9.2.5 [:]操作符&#xff1a;分片字符串 9.2.6 in操作符&#xff1a;查找子串 9.2.7 %操作符&#xff1a;格式化字符串 9…

为什么要做软件测试

随着信息技术的发展和普及&#xff0c;人们对软件的使用越来越普及。但是在软件的使用过程中&#xff0c;软件的效果却不尽如人意。为了确保软件的质量&#xff0c;整个软件业界已经逐渐意识到测试的重要性&#xff0c;软件测试已经成为IT 领域的黄金行业。本篇文章将会带领大家…

使用Tensorboard多超参数随机搜索训练

文章目录1超参数训练代码2远端电脑启动tensorboard完整代码位置https://gitee.com/chuge325/base_machinelearning.git 这里还参考了tensorflow的官方文档 但是由于是pytorch训练的差别还是比较大的&#xff0c;经过多次尝试完成了训练 硬件是两张v100 1超参数训练代码 这个…

Android Studio升级Gradle Plugin升级导致项目运行失败问题

背景&错误 升级Android Studio 旧项目无法运行&#xff0c;奇奇怪怪什么错误都有 例如&#xff1a; java.lang.IllegalAccessError: class org.gradle.api.internal.tasks.compile.processing.AggregatingProcessingStrategy (in unnamed module 0x390ea9fb) cannot acce…

传智健康-day2

一.需求分析(预约管理功能开发) 预约管理功能&#xff0c;包括检查项管理、检查组管理、体检套餐管理、预约设置等、预约管理属于系统的基础功能&#xff0c;主要就是管理一些体检的基础数据。 检查组是检查项的集合 二.基础环境搭建 1导入预约管理模块数据表 需要用到的…

Ubuntu安装MySQL及常用操作

一、安装MySQL 使用以下命令即可进行mysql安装&#xff0c;注意安装前先更新一下软件源以获得最新版本&#xff1a; sudo apt-get update #更新软件源 sudo apt-get install mysql-server #安装mysql 上述命令会安装以下包&#xff1a; apparmor mysql-client-5.7 mysql-c…

不定期更新:我对 ChatGPT 进行多方位了解后的报告,超级全面,建议想了解的朋友看看

优质介绍视频&#xff1a; GPT4前端【AI编程新纪元】 【渐构】万字科普GPT4为何会颠覆现有工作流&#xff1b;为何你要关注微软Copilot、文心一言等大模型 此文章不定期更新&#xff08;一周应该会更新一次&#xff09; 最近一次更新&#xff1a;2023.4.16 12:00 ChatGPT 是什…

零基础搭建私人影音媒体平台【远程访问Jellyfin播放器】

文章目录1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置4.公网访问测试5. 结语1. 前言 随着移动智能设备的普及&#xff0c;各种各样的使用需求也被开发出来&#xf…

关于加强供水企业营销管理的几点思考

供水营销部门是供水企业最重要的职能部门之一&#xff0c;其工作职能直接与供水企业的经济利益和社会效益息息相关&#xff0c;具体来说&#xff0c;主要涉及到五个方面的指标内容&#xff1a;水费回收率、 水量漏损率&#xff08;产销差率&#xff09;、水表完好率、水价调整及…

《年会抽奖》:无人获奖的概率

目录 一、题目 二、思路 1、错排问题 2、n 的阶乘 3、输出格式要求 三、代码 一、题目 题目&#xff1a;年会抽奖 题目链接&#xff1a;年会抽奖 今年公司年会的奖品特别给力&#xff0c;但获奖的规矩却很奇葩&#xff1a; 1. 首先&#xff0c;所有人员都将…

SpringBoot起步依赖和自动配置

文章目录 1、起步依赖2、自动配置 1、起步依赖 概念 起步依赖本质上是一个Maven项目对象模型&#xff08;Project Object Model&#xff0c;POM&#xff09;&#xff0c;定义了对其他库的传递依赖&#xff0c;这些东西加在一起支持某一功能。 简单的说&#xff0c;起步依赖就…

这才是后端API该有的样子

一般系统大致架构如下&#xff1a; 有些小伙伴会说&#xff0c;这个架构太简单太low了吧&#xff0c;什么网关、缓存、消息中间件都没有。 需要说明的是&#xff0c;因为我们主题是API接口&#xff08;tbAPI&#xff0c;pinduoduo API接口调用&#xff09;所以聚焦这一点上就行…

Java FileChannel文件的读写实例

一、概述&#xff1a; 文件通道FileChannel是用于读取&#xff0c;写入&#xff0c;文件的通道。FileChannel只能被InputStream、OutputStream、RandomAccessFile创建。使用fileChannel.transferTo()可以极大的提高文件的复制效率&#xff0c;他们读和写直接建立了通道&#x…

【Leetcode刷题】链表的中间结点和合并两个有序链表

生命如同寓言&#xff0c;其价值不在与长短&#xff0c;而在与内容。 ——塞涅卡 目录 一.链表的中间结点 1.快慢指针 二.合并两个有序链表 1.尾插法 一.链表的中间结点 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结…

Java——对象克隆(复制)

假如想复制一个简单变量。很简单&#xff1a; int apples 5; int pears apples; 不仅int类型&#xff0c;其它七种原始数据类型(boolean,char,byte,short,float,double.long)同样适用于该类情况。 但是如果你复制的是一个对象&#xff0c;情况就复杂了。 假设说我是一个b…

windows安装scoop

scoop介绍 Scoop是一款适用于Windows平台的命令行软件&#xff08;包&#xff09;管理工具。简单来说&#xff0c;就是可以通过命令行工具&#xff08;PowerShell、CMD等&#xff09;实现软件&#xff08;包&#xff09;的安装管理等需求&#xff0c;通过简单的一行代码实现软…

博客上几种新职业的工作指南

© 2019 Conmajia 我不是在嘲讽谁&#xff0c;真的&#x1f605; 看了不少博客&#xff0c;发现了一些共同点。我觉得可以把这些博主分类一下&#xff0c;形成几种新的职业。 1. 超文本抄书匠Hypertext Copier Job description 拥有悠久历史的手打大师&#xff0c;大段抄录…

2023-04-16 算法面试中常见的栈和队列问题

栈和队列 1 栈的基础应用:20.括号匹配 class Solution {public boolean isValid(String s) {Stack<Character> stack new Stack<>();for (int i 0; i < s.length(); i) {char c s.charAt(i);if (c ( || c [ || c {) {stack.push(c);} else {// 还有字符…