C++:第十三讲BFS广度优先搜索

news2024/11/16 12:34:40

前言

今天带领大家学一下BFS。

DFS可以看——C++:第十二讲DFS深搜(二)_c++匿名函数dfs-CSDN博客

BFS简介

广度优先搜索(breadth-first search,缩写为bfs)又名宽度优先搜索,是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。BFS算法从问题的初始状态(起点)出发,根据状态转换规则(图结构中的边),遍历所有可能的状态(其他节点),直到找到终结状态(终点)。因此BFS算法的复杂度和状态集合的总数密切相关。首先访问初始顶点vi,并将其标记为已访问; 接着访问vi的所有未被访问过的邻接点vi1,vi2,…,vit,并均标记为已访问;(注意与DFS算法比较)

为什么要用到BFS呢?有的时候,对于DFS而言会陷入搜索过深仍然找不到解,也就意味着超时。因此,BFS就来了。尤其在连通性,最短路等问题。

例题1——洛谷P1605迷宫

链接——BFS(洛谷P1162)

题目描述

由数字 0 组成的方阵中,有一任意形状的由数字 1 构成的闭合圈。现要求把闭合圈内的所有空间都填写成 2。例如:6×6 的方阵(n=6),涂色前和涂色后的方阵如下:

如果从某个 0出发,只向上下左右 4 个方向移动且仅经过其他 0 的情况下,无法到达方阵的边界,就认为这个 0在闭合圈内。闭合圈不一定是环形的,可以是任意形状,但保证闭合圈内的 0 是连通的(两两之间可以相互到达)。

0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 1 0 1
1 1 1 1 1 1
0 0 0 0 0 0
0 0 0 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 1 2 1
1 1 1 1 1 1

输入格式

每组测试数据第一行一个整数 n(1≤n≤30)。

接下来 n 行,由 0 和 1组成的 n×n 的方阵。

方阵内只有一个闭合圈,圈内至少有一个 0。

输出格式

已经填好数字 2的完整方阵。

输入输出样例

输入 #1

6
0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 0 0 1
1 1 0 0 0 1
1 0 0 0 0 1
1 1 1 1 1 1

输出 #1

0 0 0 0 0 0
0 0 1 1 1 1
0 1 1 2 2 1
1 1 2 2 2 1
1 2 2 2 2 1
1 1 1 1 1 1

说明/提示

对于 100% 的数据,1≤n≤30。

解题思路

首先,分析题目,这是要将闭合的“1”里面的“0”改写成“2”,然后输出。由此,我们猛然发觉,只要‘0’的联通块中,没有在边界,就是闭合的‘0’;(发现这个,就等于做对了一半;)因为,从正面推,找闭合中的‘0’不好找。所以,蒟蒻想到,运用BFS或者DFS直接搜索边界中‘0’,所在的联通块,然后标记。最后输出时,去除‘1’点和标记了的点,剩下的输出为‘2’,就是正解啦!!!

AC

#include <bits/stdc++.h>
using namespace std;
int N,A[55][55];
bool Flag[55][55];
int Dx[5]={0,-1,1,0,0};
int Dy[5]={0,0,0,-1,1};
void DFS(int i,int j){
	//越界 
	if(i<0||j<0||i>N+1||j>N+1) return ;
	//遍历过或者为1 
	if(Flag[i][j]==true||A[i][j]==1) return;
	Flag[i][j]=true; 
	for(int nx=1;nx<=4;nx++) DFS(i+Dx[nx],j+Dy[nx]);
	return ;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>N;
	//最外面的零层都是零(相当于在外面套一圈)
	//避免从左上角开始时是1 
	for(int i=1;i<=N;i++)
	 for(int j=1;j<=N;j++)
	    cin>>A[i][j]; 
	DFS(0,0);
	for(int i=1;i<=N;i++){	 
	  for(int j=1;j<=N;j++){
	 	//搜索不到的零 
	 	if(!A[i][j]&&Flag[i][j]==false) cout<<2<<" ";
		else cout<<A[i][j]<<" "; 
	  }
	  cout<<endl;	
	}

	return 0;
} 

 例题2——洛谷P1443马的遍历

链接——BFS(洛谷P1443)

题目描述

有一个 n×m 的棋盘,在某个点 (x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。

输入格式

输入只有一行四个整数,分别为 n,m,x,y。

输出格式

一个n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 −1−1)。

输入输出样例

输入 #1

3 3 1 1

输出 #1

0    3    2   
3    -1   1   
2    1    4    

说明/提示

数据规模与约定

对于全部的测试点,保证 1≤x≤n≤400,1≤y≤m≤400。

解题思路

选择解决方案:

从一个点出发,搜寻另外的点,这明显是一道关于搜索的题目。至于用到深搜还是广搜,见下表:

从上图我们看到,BFS专门用于解决求两点之间最短路的问题,而DFS是用来解决求一个点到另一个点路径总数的问题。显然地,这题用到的是BFS。

注意事项:

“马走日,象走田”,在棋盘上,马按照“日”字的走法移动,对应到我们的数组大概是这样的:

(PS:其中红色为出发点,黄色为可到达的点)

我们发现,从[4][6]a[4][6]出发,可到达的点为:[2][5]a[2][5]、[3][4]a[3][4]、[2][7]a[2][7]、[3][8]a[3][8]、[5][4]a[5][4]、[6][5]a[6][5]、[6][7]a[6][7]、[5][8]a[5][8]。

AC

#include<bits/stdc++.h>
using namespace std;
int n,m,x,y;
int hor[405][405];
bool vis[405][405];
int dx[]={1,2,-1,-2,-2,-1,1,2};
int dy[]={2,1,2,1,-1,-2,-2,-1};
void bfs(){
	queue<int> x1;
	queue<int> y1;
	//将马的初始位置放入队列中
	x1.push(x);
	y1.push(y);
	while(!x1.empty()){
		for(int i=0;i<8;i++){
			int xx=x1.front()+dx[i];
			int yy=y1.front()+dy[i];
			if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&!vis[xx][yy]){
				vis[xx][yy]=true;
				hor[xx][yy]=hor[x1.front()][y1.front()]+1;
				x1.push(xx);
				y1.push(yy);
			}	
		}
		x1.pop();
		y1.pop();
	}
}
int main(){
	cin>>n>>m>>x>>y;
	memset(hor,-1,sizeof(hor));
	hor[x][y]=0;
	vis[x][y]=true;
	bfs();
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			printf("%-5d",hor[i][j]);
		}
		cout<<endl;
	}
}

课后练习(拓展难题)

链接——BFS(洛谷P1902)

题目描述

某组织正在策划一起对某大使的刺杀行动。他们来到了使馆,准备完成此次刺杀,要进入使馆首先必须通过使馆前的防御迷阵。

迷阵由 n×m 个相同的小房间组成,每个房间与相邻四个房间之间有门可通行。在第 n 行的 m 个房间里有 m 个机关,这些机关必须全部打开才可以进入大使馆。而第 11 行的 m 个房间有 m 扇向外打开的门,是迷阵的入口。除了第 11 行和第 n 行的房间外,每个房间都被使馆的安保人员安装了激光杀伤装置,将会对进入房间的人造成一定的伤害。第 i 行第 j 列 造成的伤害值为 pi,j​(第 11 行和第 n 行的 p 值全部为 00)。

现在某组织打算以最小伤害代价进入迷阵,打开全部机关,显然,他们可以选 择任意多的人从任意的门进入,但必须到达第 n 行的每个房间。一个士兵受到的伤害值为他到达某个机关的路径上所有房间的伤害值中的最大值,整个部队受到的伤害值为所有士兵的伤害值中的最大值。现在,这个恐怖组织掌握了迷阵的情况,他们需要提前知道怎么安排士兵的行进路线可以使得整个部队的伤害值最小。

输入格式

第一行有两个整数 n,m,表示迷阵的大小。

接下来 n 行,每行 m 个数,第 i 行第 j 列的数表示 pi,j​。

输出格式

输出一个数,表示最小伤害代价。

输入输出样例

输入 #1

4 2
0 0
3 5
2 4
0 0 

输出 #1

3

说明/提示

  • 50%的数据,n,m≤100;

  • 100%的数据,n,m≤1000,pi,j​≤1000。 

解题思路

题目概括出来,很容易想到二分。

求最大值最小,因此我们可以对最大伤害值进行二分。

如果某位置所受伤害值大于我们当前所限制的伤害值,我们肯定是不走这条路的.

AC

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
typedef long long ll;
typedef pair<ll,ll> pll;
int mod=1e9+7;
const int maxv=4e6+5;
ll n,m;
int a[1005][1005];
int get(int x,int y)//得到点的编号
{
	return (x-1)*m+y;
}
int p[maxv];
struct node
{
	int u,v,w;
}e[maxv];
int k;
int find(int x)
{
	if(p[x]!=x) return p[x]=find(p[x]);
	return p[x];
}
void solve()
{	
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
			int c=get(i,j);
			p[c]=c;
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			int u=get(i,j);
			int v1=get(i+1,j);
			int v2=get(i,j+1);
			if(i+1<=n) e[k++]={u,v1,max(a[i][j],a[i+1][j])};
			if(j+1<=m) e[k++]={u,v2,max(a[i][j],a[i][j+1])};
		}
	}
	sort(e,e+k,[](node a,node b){
		return a.w<b.w;
	});
	int ans=0;
	int st=1,ed=n*m;
	for(int i=0;i<k;i++){
		int u=e[i].u,v=e[i].v,w=e[i].w;
		//cout<<u<<" "<<v<<" "<<w<<endl;
		int fu=find(u),fv=find(v);
		if(fu!=fv){
			p[fu]=fv;
			ans=max(ans,w);
		}
		if(find(st)==find(ed)) break;
	}
	cout<<ans<<endl;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	t=1;
	while(t--){
		solve();
	}
	system("pause");
	return 0;
}

结尾

希望大家多多关注,下一个红包就在这!!!

本篇文章共5434字,如果你能支持一下我,我十分感谢!!!

如果有人想在洛谷上做题,可以点下方链接:

https://www.luogu.com.cn/

如果你喜欢或想了解一下其他的算法,可以看看以下这些:

题目详解系列(部分):

【万题详解】洛谷P1252 马拉松接力赛-CSDN博客

【万题详解】洛谷P1359 租用游艇-CSDN博客 

【百题详解】洛谷P8508 做不完的作业-CSDN博客

【万题详解1】洛谷P1230 智力大冲浪-CSDN博客

【全网首发】洛谷贪心题解集合-CSDN博客

洛谷二分题集(3题)-CSDN博客

游戏系列:

C++:史上最坑小游戏-CSDN博客

 C++:自创小游戏-CSDN博客

C++:下雪-CSDN博客

C++讲解系列(算法):

C++:第十二讲DFS深搜(二)_c++匿名函数dfs-CSDN博客

 C++:第十一讲DFS深搜-CSDN博客

C++:第十讲二分查找-CSDN博客

前缀和与差分:

C++:第九讲前缀和与差分-CSDN博客

贪心:

C++:第八讲贪心算法1-CSDN博客

C++讲解系列(基础入门):

排序:

C++:第七讲冒泡排序-CSDN博客

函数:

C++第6讲max和min函数_c++ min函数-CSDN博客

C++第五讲函数初步-CSDN博客

for循环&数组:

C++第四讲for循环及数组-CSDN博客

if语句&else语句及运算:

C++第三讲:C++中的逻辑运算符及if else语句-CSDN博客

基础:

C++第二讲输入与输出-CSDN博客

C++第一讲认识C++编译器-CSDN博客

欢迎收看,希望大家能三连!

最后认识一下,我是爱编程的喷火龙廖,我们有缘再见!

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

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

相关文章

Conda python运行的包和环境管理 入门

Conda系列&#xff1a; 翻译: Anaconda 与 miniconda的区别Miniconda介绍以及安装 Conda 是一个功能强大的命令行工具&#xff0c;用于在 Windows、macOS 和 Linux 上运行的包和环境管理。 本 conda 入门指南介绍了启动和使用 conda 创建环境和安装包的基础知识。 1. 准备…

优先级队列(堆) PriorityQueue

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 1.优先级队列 2.优先级队列的模拟实现 2.1 堆的概念 2.2 堆的创建 2.3 堆的插入和删除 2.…

基于openssl v3搭建ssl安全加固的c++ tcpserver

1 概述 tcp server和tcp client同时使用openssl库&#xff0c;可对通信双方流通的字节序列进行加解密&#xff0c;保障通信的安全。本文以c编写的tcp server和tcp client为例子&#xff0c;openssl的版本为v3。 2 安装openssl v3 2.1 安装 perl-IPC-Cmd openssl项目中的co…

【软考】位示图

目录 一、基本概念二、位示图 一、基本概念 1.要将文件保存到外部存储器&#xff08;外存或辅存&#xff09;&#xff0c;首先得知道存储空间的使用情况 2.要清楚哪个物理块已经被占用&#xff0c;哪个物理块是空闲的 3.当对大容量的磁盘存储空间被多用户共享时&#xff0c;用户…

套接字通信(附带单线程TCP套接字通信代码)

套接字-Socket 1. 概念 1.1 局域网和广域网 局域网&#xff08;LAN&#xff09;和广域网&#xff08;WAN&#xff09;是两种不同范围的计算机网络&#xff0c;它们用于连接多台计算机以实现数据共享和通信。 局域网&#xff08;LAN&#xff09;&#xff1a; 定义&#xff1…

JUC-CAS

1. CAS概述 CAS(Compare ans swap/set) 比较并交换&#xff0c;实现并发的一种底层技术。它将预期的值和内存中的值比较&#xff0c;如果相同&#xff0c;就更新内存中的值。如果不匹配&#xff0c;一直重试&#xff08;自旋&#xff09;。Java.util.concurrent.atomic包下的原…

AMIS的组件学习使用

部分代码片段 {"id": "filterForm","className": " xysd-zbkb-pubquery","labelWidth": 130,"body": [{"type": "grid","className": "xysd-grid-query-input","c…

鲲鹏微认证——openEuler开源操作系统迁移实践

文章目录 为什么要系统搬迁为什么选择欧拉欧拉系统迁移概述实施路径工具实战 为什么要系统搬迁 2020年12月&#xff0c;CentOs作为由开源社区免费提供的操作系统&#xff0c;宣布将对CentO58于2021年底停止服务&#xff0c;CentO57则于2024年6月底停止服务。 这将直接导致操作…

MyBatis详解(1)-- ORM模型

MyBatis详解&#xff08;1&#xff09; JDBC的弊端&#xff1a; ORM 模型常见的ORM模型&#xff1a;mybatis和Hibernate的区别 ***优势&#xff1a;mybatis解决问题&#xff1a;优点&#xff1a; MyBatisMyBatis环境搭建项目架构mybatis生命周期 JDBC的弊端&#xff1a; 1.硬编…

dataGrip连接数据库mysql和intersystems的iris

intersystems公司的产品iris是cache的升级版本&#xff0c;目前绝大多数数据库工具都没法连接这个数据库 datagrip下载地址 https://download-cdn.jetbrains.com.cn/datagrip/datagrip-2023.3.3.exe 选择对应的数据库产品类型 新建数据库资源连接 填上对应的数据库连接和账…

12.前端--CSS-背景属性

1.背景颜色 样式名称&#xff1a; background-color 定义元素的背景颜色 使用方式: background-color:颜色值; 其他说明&#xff1a; 元素背景颜色默认值是 transparent&#xff08;透明&#xff09;      background-color:transparent; 代码演示&#xff1a; 背景色…

将AWS iot消息数据发送Kinesis Firehose Stream存向S3

观看此文章之前&#xff0c;请先学习AWS iot的数据收集&#xff1a; 使用Linux SDK客户端向AWS Iot发送数据-CSDN博客 1、工作原理&#xff1a; 1.1 规则 规则可让您的设备与 AWS 服务进行交互。分析规则并根据物品发送的消息执行操作。您可以使用规则来支持任务&#xff0…

Lucene 源码分析——BKD-Tree

Lucene 源码分析——BKD-Tree - AIQ Bkd-Tree Bkd-Tree作为一种基于K-D-B-tree的索引结构&#xff0c;用来对多维度的点数据(multi-dimensional point data)集进行索引。Bkd-Tree跟K-D-B-tree的理论部分在本篇文章中不详细介绍&#xff0c;对应的两篇论文在附件中&#xff0c…

配置ntp时间服务器和ssh免密登录实验

1&#xff1a;配置ntp时间服务器&#xff0c;确保客户端主机能和服务主机同步时间 第一步&#xff0c;将服务器的时间同步对象改为阿里的时间服务器&#xff08;这样比较精准&#xff09; 先启动服务&#xff1a;[rootserver ~]# systemctl start chronyd 进入配置文件&#xf…

源 “MySQL 5.7 Community Server“ 的 GPG 密钥已安装,但是不适用于此软件包。请检查源的公钥 URL 是否配置正确

Is this ok [y/d/N]: y Downloading packages: 警告&#xff1a;/var/cache/yum/x86_64/7/mysql57-community/packages/mysql-community-server-5.7.44-1.el7.x86_64.rpm: 头V4 RSA/SHA256 Signature, 密钥 ID 3a79bd29: NOKEY 从 file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql 检…

知识图谱符号表示比较:特性图、RDF和OWL

目录 前言1 特性图&#xff1a;灵活的图结构表示1.1 优势与灵活性1.2 存储优化与查询优势1.3 挑战&#xff1a;缺乏工业标准支持 2 RDF&#xff08;Resource Description Framework&#xff09;&#xff1a;面向Web的数据标准2.1 三元组结构的优势2.2 语义标准与词汇丰富性2.3 …

蓝桥杯备战——1.点亮LED灯

1.解析原理图 由上图可以看到8个共阳LED灯接到了573输出口&#xff0c;而573输入接到单片机P0口上。当573 LE脚输入高电平时&#xff0c;输出随输入变化&#xff0c;当LE为低电平时&#xff0c;输出锁存。 由上图可以看到Y4C接到了或非门74HC02的输出端&#xff0c;而输入端为…

顺序表的增、删、改、查

小伙伴们好&#xff0c;学完C语言&#xff0c;就要开始学数据结构了&#xff0c;数据结构也是非常重要的&#xff0c;今天我们主要来学习在数据结构中最常用的增删改查操作。话不多说&#xff0c;一起来学习吧 1.数据结构相关概念 1.什么是数据结构&#xff1f; 数据结构是由…

【Web前端开发基础】CSS3之Web字体、字体图标、平面转换、渐变

CSS3之Web字体、字体图标、平面转换、渐变 目录 CSS3之Web字体、字体图标、平面转换、渐变一、Web字体1.1 Web字体概述1.2 字体文件1.3 font-face 规则 二、字体图标2.1 字体图标2.2 字体图标的优点2.3 图标库2.4 下载字体包2.5 字体图标的使用步骤2.6 字体图标使用注意点2.7 上…

12.常用统计分析方法——聚类分析

目录 基础知识 实操 层次聚类 划分聚类 方法一&#xff1a;K均值聚类&#xff08;最常见&#xff09; 方法二&#xff1a;基于中心点的划分&#xff08;PAM&#xff09; 避免不存在的类 基础知识 概念&#xff1a; 聚类分析是一种数据归约技术&#xff0c;旨在揭露一个…