首页 > 其他分享 >搜索(DFS/BFS)

搜索(DFS/BFS)

时间:2023-07-20 20:44:48浏览次数:35  
标签:int Luogu DFS BFS 搜索 dfs ans

广度优先搜索(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(缩小规模);
              撤回操作;
            }
        }
        

标签:int,Luogu,DFS,BFS,搜索,dfs,ans
From: https://www.cnblogs.com/moilip/p/17569623.html

相关文章

  • mysql 把搜索结果作为子集
    如何在MySQL中将搜索结果作为子集作为一名经验丰富的开发者,你经常需要在数据库中进行搜索并使用搜索结果作为子集来进一步处理数据。在MySQL中,你可以使用子查询来实现这个目标。下面我将向你介绍整个流程,并提供详细的代码示例。流程概览下面是在MySQL中将搜索结果作为子集......
  • 冷门科技 —— DFS 序求 LCA
    Updateon2023.7.17:该技巧目前已知的最早来源:skip2004。Updateon2023.7.17:比较时,取时间戳较小的结点也是正确的,不用记录深度。DFS序求LCA无论是从时间常数,空间常数还是好写程度方面均吊打欧拉序。定义DFS序表示对一棵树进行深度优先搜索得到的结点序列,而时间戳DFN......
  • 小明以 hadoop 用户身份在 HDFS 上 hadoop 目录下创建 expl 目录时,发现该目
    使用Hadoop创建目录引言Hadoop是一个开源的分布式计算框架,提供了可靠性和高可扩展性的存储和处理大数据的能力。其中的分布式文件系统HDFS(HadoopDistributedFileSystem)是Hadoop的核心组件之一,用于存储和管理海量数据。在HDFS上进行目录和文件的操作是使用Hadoop命令行工具或者......
  • SaeweedFS操作
    #mdir存储元数据的数据目录#port监听端口#peers主节点ip:端口#defaultReplication备份策略#ip服务器ip#garbageThreshold清空和回收空间的阈值#maxCpu最大cpu数量,0是所有#pulseSeconds心跳检测的时间间隔单位为秒#ip.bind绑......
  • Docker安装的fastdfs基于不同服务器的数据迁移
    首先,基于docker搭建新的fastdfs中间件,参考地址为:https://blog.csdn.net/ming19951224/article/details/126933299然后将原服务器的storage文件夹下的data文件夹进行备份,打包成bak.zip 将bak.zip下载后上传到新服务器的storage文件夹下 使用unzip解压缩bak.zip,然后进入data.......
  • ABAP文件夹搜索帮助
      DATA:  lv_folder   TYPE string.     CALL METHOD cl_gui_frontend_services=>directory_browse      EXPORTING        WINDOW_TITLE  = '请选择要下载路径文件夹'      CHANGING        selected_folder = lv_folder   ......
  • dfs优化剪枝
    题目链接:D-PeacefulTeams(atcoder.jp)先看数据范围,肯定是搜索相关首先想到从第1个人,第0个队开始的搜索顺序,因为这属于内部顺序,所以每次搜索要回溯状态,注意要进行大量剪枝#include<bits/stdc++.h>usingnamespacestd;usingull=unsignedlonglong;usingll=lon......
  • LeetCode 35.搜索插入位置
    题目:给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。请必须使用时间复杂度为 O(logn) 的算法。示例1:输入:nums=[1,3,5,6],target=5输出:2示例 2:输入:nums=[1,3,5,6],target=2输出:1......
  • hdu 1010 Tempter of the Bone (dfs+奇偶剪枝)
    小记:最开始以为是T时间内,用bfsWA了,后来知道是刚好T时间,然后就用dfs,相当于暴力了,然后简单的dfs提交TLE,必须剪枝。首先判最少需要的时间是否有,没有就不用继续了,而如果有,那么因为我们是要花掉T时间刚好到达,那么我们先保证能走到终点的时间,然后在路上花掉多余的时间此时,我们必须保证......
  • leetcode104二叉树搜索
    深度优先搜索,递归maxDepth(TreeNode*root){if(!root)return0;returnmax(maxDepth(root->left),maxDepth(root->right))+1;} 广度优先搜索,队列queue<TreeNode*>q;q.push(root);while(!q.empty()){intsize=q.size();while(size>0){Tree......