搜索(DFS/BFS)
广度优先搜索(BFS)
基本要点:
- 利用队列(先进先出)
- 一层一层搜索
- 适合于连通块的搜索
- 任何的BFS都可以转化为对树的广搜
基本流程:
- 选择搜索的起点,起点入队,起点标记为已访问
- 队列非空时,循环出队,每次出队将与出队元素连通的且未访问过的元素依次入队,并标记为已访问
基础模板:
void DFS(int x,int y){
q.push(start);
vis[start] = 1;
while(!q.empty()){
int x = q.front();
q.pop();
for(所有与x联通的y){
if(vis[y] == 0){
q.push(y); vis[y] = 1;
}
}
}
}
题型归纳:
- [[Luogu P1451 求细胞数量]]
- [[Luogu P1162 填涂颜色]]
- [[Luogu P1443 马的遍历]]
- [[Luogu P3958 奶酪]]
- 题型总结:邻接条件一般是:1.增量数组(上下左右) 2.邻接矩阵(是否有边相连)
深度优先搜索(DFS)
基本要点:
- 通常用于解决最大/最长路径或者穷举所有可能的问题
- 用递归来实现
- 一条路走到黑
- 任何的DFS都可以转化为对树的深搜
基本流程:
- 选择一个起点进入DFS搜索
- 对于当前阶段/节点有多种处理决策,选择第一个决策,然后DFS下一个阶段
- 当第一个决策执行完毕后回溯,执行下一个决策
-
基础模板:
//非回溯版
void DFS(int x,int y){
cnt++;//用于记录遍历的节点数的变量
vis[x][y] = 1;//在DFS内部标记已访问不用回溯
for(int i = 1; i < 4; ++ i){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx >= 1 && nx <= n && ny >= 1 && ny <= n && vis[nx][ny] == 0)
DFS(nx,ny);
}
} //回溯版
void DFS(int x,int y){
cnt++;//用于记录遍历的节点数的变量
for(int i = 1; i < 4; ++ i){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx >= 1 && nx <= n && ny >= 1 && ny <= n && vis[nx][ny] == 0){
vis[nx][ny] = 1;
DFS(nx,ny);
vis[nx][ny] = 0;//在DFS外部标记已访问要回溯
} }
}
题型归纳:
- [[Luogu B3625 迷宫寻路]]
- [[Luogu P1706 全排列问题]]
- [[Luogu P4017 最大食物链计数]]
- [[Luogu P1219 八皇后]]
搜索剪枝优化:
- 记忆化搜索:
- 基本要点:
- 添加一个记忆化数组,对访问过的元素标记,避免重复访问
- 一般在递归函数中使用,当当前元素已经访问过时,直接返回值,跳过对该元素的处理
- 多用于动态规划的过程 - 基础模板:
int g[MAXN]; // 定义记忆化数组
int ans = 最坏情况, now;
void dfs f(传入数值) {
if (g[规模] != 无效数值) return; // 或记录解,视情况而定
if (到达目的地) ans = 从当前解与已有解中选最优; // 输出解,视情况而定
for (遍历所有可能性)
if (可行) {
进行操作;
dfs(缩小规模);
撤回操作;
}
} int main() {
// ...
memset(g, 无效数值, sizeof(g)); // 初始化记忆化数组
// ...
}
- 题型归纳:
[[Luogu P4017 最大食物链计数]]
- 基本要点:
- 最优性剪枝:
- 基本要点:
- 在搜索中导致运行慢的原因还有一种,就是在当前解已经比已有解差时仍然在搜索,那么我们只需要判断一下当前解是否已经差于已有解。 - 基础模板:
int ans = 最坏情况, now;
void dfs(传入数值) {
if (now比ans的答案还要差) return;
if (到达目的地) ans = 从当前解与已有解中选最优;
for (遍历所有可能性)
if (可行) {
进行操作;
dfs(缩小规模);
撤回操作;
}
}
- 基本要点:
- 可行性剪枝:
- 基本要点:
-在搜索过程中当前解已经不可用了还继续搜索下去也是运行慢的原因。 - 基础模板:
int ans = 最坏情况, now;
void dfs(传入数值) {
if (当前解已不可用) return;
if (到达目的地) ans = 从当前解与已有解中选最优;
for (遍历所有可能性)
if (可行) {
进行操作;
dfs(缩小规模);
撤回操作;
}
}
- 基本要点:
- 记忆化搜索:
搜索(DFS/BFS)的更多相关文章
- POJ 2243 简单搜索 (DFS BFS A*)
题目大意:国际象棋给你一个起点和一个终点,按骑士的走法,从起点到终点的最少移动多少次. 求最少明显用bfs,下面给出三种搜索算法程序: // BFS #include<cstdio> #i ...
- 搜索进阶课件,视频,代码(状态压缩搜索,折半搜索,dfs,bfs总结)
链接:https://pan.baidu.com/s/1-svffrprCOO4CtQoCTQ9hQ 提取码:h909 复制这段内容后打开百度网盘手机App,操作更方便哦
- 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)
深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...
- 深度优先搜索(DFS)与广度优先搜索(BFS)的Java实现
1.基础部分 在图中实现最基本的操作之一就是搜索从一个指定顶点可以到达哪些顶点,比如从武汉出发的高铁可以到达哪些城市,一些城市可以直达,一些城市不能直达.现在有一份全国高铁模拟图,要从某个城市(顶点) ...
- 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)
需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...
- 深度优先搜索(DFS)和广度优先搜索(BFS)
深度优先搜索(DFS) 广度优先搜索(BFS) 1.介绍 广度优先搜索(BFS)是图的另一种遍历方式,与DFS相对,是以广度优先进行搜索.简言之就是先访问图的顶点,然后广度优先访问其邻接点,然后再依次 ...
- 深度优先搜索DFS和广度优先搜索BFS简单解析
转自:https://www.cnblogs.com/FZfangzheng/p/8529132.html 深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每 ...
- Leetcode之深度+广度优先搜索(DFS+BFS)专题-934. 最短的桥(Shortest Bridge)
Leetcode之广度优先搜索(BFS)专题-934. 最短的桥(Shortest Bridge) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary ...
- hdu 1254 推箱子(嵌套搜索,bfs中有dfs)
推箱子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- 深度优先搜索(DFS)和广度优先搜索(BFS)求解迷宫问题
用下面这个简单的迷宫图作为例子: OXXXXXXX OOOOOXXX XOXXOOOX XOXXOXXO XOXXXXXX XOXXOOOX XOOOOXOO XXXXXXXO O为通路,X为障碍物. ...
随机推荐
- [Pytorch框架] 1.1、Pytorch简介
文章目录 1.1 Pytorch 简介 1.1.1 PyTorch的由来 1.1.2 Torch是什么? 1.1.3 重新介绍 PyTorch 1.1.4 对比PyTorch和Tensorflow 1 ...
- 2022-11-07:给你一个 n 个节点的 有向图 ,节点编号为 0 到 n - 1 ,其中每个节点 至多 有一条出边。 图用一个大小为 n 下标从 0 开始的数组 edges 表示, 节点 i 到
2022-11-07:给你一个 n 个节点的 有向图 ,节点编号为 0 到 n - 1 ,其中每个节点 至多 有一条出边. 图用一个大小为 n 下标从 0 开始的数组 edges 表示, 节点 i 到 ...
- 2022-02-17:寻找最近的回文数。 给定一个表示整数的字符串 n ,返回与它最近的回文整数(不包括自身)。如果不止一个,返回较小的那个。 “最近的”定义为两个整数差的绝对值最小。 示例 1: 输
2022-02-17:寻找最近的回文数. 给定一个表示整数的字符串 n ,返回与它最近的回文整数(不包括自身).如果不止一个,返回较小的那个. "最近的"定义为两个整数差的绝对值最 ...
- 2021-05-17:数组中所有数都异或起来的结果,叫做异或和。给定一个数组arr,可以任意切分成若干个不相交的子数组。其中一定存在一种最优方案,使得切出异或和为0的子数组最多。返回这个最多数量。
2021-05-17:数组中所有数都异或起来的结果,叫做异或和.给定一个数组arr,可以任意切分成若干个不相交的子数组.其中一定存在一种最优方案,使得切出异或和为0的子数组最多.返回这个最多数量. 福 ...
- 2022-01-11:给定一个正数数组arr长度为n、正数x、正数y。 你的目标是让arr整体的累加和<=0, 你可以对数组中的数num执行以下三种操作中的一种,且每个数最多能执行一次操作 : 1.
2022-01-11:给定一个正数数组arr长度为n.正数x.正数y. 你的目标是让arr整体的累加和<=0, 你可以对数组中的数num执行以下三种操作中的一种,且每个数最多能执行一次操作 : ...
- Django4全栈进阶之路10 url路由设置
在 Django 4 中,可以在主路由文件中设置和管理子路由.通常,我们会为每个应用程序创建一个子路由文件,以便更好地组织代码和管理路由. 以下是 Django 4 中设置主路由和子路由的示例: 首先 ...
- 【工作随手记】deaklock排查
生产环境当中还没真正遇到过死锁的问题.有些疑似死锁的问题,后来经过排查也只是其它问题导致的.所以通过jstack到底怎样排查死锁问题有点疏忽了.这里作个记录. 模拟一个死锁 顺便复习一下. 死锁的产生 ...
- ArcMap手动新建矢量要素的方式
本文介绍在ArcGIS下属ArcMap软件中,新建点.线.面等矢量要素图层,并对新建图层的空间范围加以划定的方法. 首先,在右侧"Catalog"栏中选择需要存放新建立矢量 ...
- 驱动开发:内核解析PE结构导出表
在笔者的上一篇文章<驱动开发:内核特征码扫描PE代码段>中LyShark带大家通过封装好的LySharkToolsUtilKernelBase函数实现了动态获取内核模块基址,并通过ntim ...
- 第一章 Rust基本知识 -- tour of rust
第一章 基础知识 将探讨函数.变量和最基本的类型等基本知识. 变量 变量使用let关键字来声明. 在赋值时,Rust能够在99%的情况下推断变量类型.如果不能,也可以将类型添加到变量声明中. 注意 如 ...