图论基础知识 深度搜索(DFS,Depth First Search),广度搜索(BFS,Breathe First Search)

图论基础知识

学习记录自代码随想录

dfs 与 bfs 区别

dfs是沿着一个方向去搜,不到黄河不回头,直到搜不下去了,再换方向(换方向的过程就涉及到了回溯)。
bfs是先把本节点所连接的所有节点遍历一遍,走到下一个节点的时候,再把连接节点的所有节点遍历一遍,搜索方向更像是广度,四面八方的搜索过程。

深度优先搜索理论(Depth First Search, 简称DFS)

搜索方向,是认准一个方向搜,直到碰壁之后再换方向
换方向是撤销原路径,改为节点链接的下一个路径,回溯的过程。

回溯算法模板

// 1.确定返回值和参数
void backtracking(参数){// 2.确定回溯终止条件if(终止条件){// 存放结果;return;	}// for横向遍历for(选择:本层集合中元素(树种节点孩子的数量就是集合的大小)){处理节点;// 纵向遍历backtracking(路径,选择列表); // 递归回溯,撤销处理结果}
}

回溯算法模板,其实就是dfs框架

// 1.确定递归函数返回值和参数,一般无返回值
一般情况下深搜需要二维数组结构保存所有路径,需要一维数组保存单一路径,
可定义全局变量
vector<vector<int>> result; // 保存符合条件的所有路径
vector<int> path; // 起点到终点的路径
void dfs(参数){// 2.确定回溯终止条件if(终止条件){// 存放结果;return;	}// 3.处理目前节点出发的路径// for横向遍历for(选择:本节点所连接的其他节点){处理节点;// 纵向遍历dfs(图,选择的节点); // 递归回溯,撤销处理结果}
}

广度优先搜索(Breath First Search, 简称BFS)

广搜的使用场景
广搜的搜索方式就适合于解决两个点之间的最短路径问题。
因为广搜是从起点出发,以起始点为中心一圈一圈进行搜索,一旦遇到终点,记录之前走过的节点就是一条最短路。
当然,也有一些问题是广搜 和 深搜都可以解决的,例如岛屿问题,这类问题的特征就是不涉及具体的遍历方式,只要能把相邻且相同属性的节点标记上就行。 (我们会在具体题目讲解中详细来说)
在这里插入图片描述

正是因为BFS一圈一圈的遍历方式,所以一旦遇到终止点,那么一定是一条最短路径。
在这里插入图片描述

广搜代码模板(针对四方格地图)

int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1};  // 表示四个方向
// grid为二维数组,地图
// visited标记访问过的节点
void bfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y){que<pair<int, int>> que;  // 定义队列que.push({x,y});  // 起始点加入队列visited[x][y] = true;  // 只要加入队列,立刻标记为访问过的节点while(!que.empty()){pair<int, int> cur = que.front();que.pop();  // 从队列种取元素int cur_x = cur.first;int cur_y = cur.second;for(int i = 0; i < 4; i++){  // 从开始节点的四个方向上右左下遍历// 获取周边四个节点坐标int next_x = cur_x + dir[i][0];int next_y = cur_y + dir[i][1]; // 坐标越界直接跳过if(next_x < 0 || next_x >= grid.size() || next_y < 0 || next_y >= grid.size()){continue;}// 若节点未被访问过if(!visited[next_x][nenxt_y]){// 队列添加新节点供下一轮遍历que.push({next_x, next_y});// 只要加入队列,代表被访问过,进行标记,防止重复访问visited[next_x][next_y] = true;	}}}
}

例题:华为20240410机考

//第二题 会议通知转发总人数
//在一个办公区内,有一些正在办公的员工,当员工A收到会议通知,
//他会将这个会议通知转发给周围四邻(上下左右工位的同事)团队内的同事,
//周围收到该邮件的同事会继续转发给周围四邻(上下左右工位的同事团队内的同事,
//直到周围没有再需要往下传播的同事则会停止;同时此扩散还有前提条件,给定一可收到该邮件的团队列表relations, 
//扩散时若该同事所在团队在relations列表中,则可进行扩散,否则不可进行扩散。
//办公室用一个二维数组office表示,其中office[i][j]表示该同事的团队名称,
//其中团队名称用整数t范围内的数字表示,i,j表示该同事的工位位置。
//
//现给定办公区的工位总行数与每一行的具体工位人员分布以及收到会议通知员工A的工位位置的坐标位置i,j : 
//还有与该邮件关联的团队编号列表relations, 请分析得出最终会有多少同事收到该会议的转发通知。
//
//注意:1、该办公区位置用二维数组表示,该二维数组以左上角的工位为起点(0, 0), 
//按照横轴向右纵轴向下的方向展开;原始收到会议通知的员工A不包含在总人数中。
//2、扩散时若该同事与收到初始收到邮件的员工A属于同一团队,
//若该团队名不在可收到通知的团队列表relations中,依然不可收到该邮件转发//输入
//第一行是一个整数n, 表示该办公区共有多少排,即就是office.length
//第二行是一个整数m, 标识该办公区共有多少列,即就是offce[i].length
//接下来n行表示每一排员工的具体分布情况,每个工位上的员工所在的团队号x用空格隔开
//接下来一行是两个数字用空格隔开,表示收到会议通知员工的工位位置,i表示横坐标位置,j表示纵坐标位置
//最后一行是一个字符串,表示可收到该邮件的团队列表relations, 团队名称之间用空格隔开
//提示:
//0 <= i <= 1000
//0 <= j <= 1000
//1 <= t <= 50
//1 <= relations.length <= 50//输出
//输出收到转发会议通知的总人数。//样例输入1
//5
//5
//1 3 5 2 3
//2 2 1 3 5
//2 2 1 3 3
//4 4 1 1 1
//1 1 5 1 2
//2 2
//1
//样例输出1
//5//样例输入2
//2
//2
//1 1
//2 2
//0 0
//2
//样例输出2
//2#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <queue>
#include <algorithm>using namespace std;class Solution {
public:int getmaxNum(vector<vector<int>>& office, vector<vector<bool>>& visited, int i, int j, vector<int>& relations) {int dir[4][2] = { 0, 1, 1, 0, -1, 0, 0, -1 };int cnt = 0;queue<pair<int, int>> que;que.push({ i, j });visited[i][j] = 1;while (!que.empty()){auto cur = que.front();que.pop();int cur_x = cur.first, cur_y = cur.second;for (int k = 0; k < 4; k++) {int next_x = cur_x + dir[k][0];int next_y = cur_y + dir[k][1];if (next_x < 0 || next_x >= office.size() || next_y < 0 || next_y >= office[0].size()) continue;if (!visited[next_x][next_y] && (find(relations.begin(), relations.end(), office[next_x][next_y]) != relations.end())) {que.push({ next_x, next_y });visited[next_x][next_y] = true;cnt++;}}}return cnt;}
};int main() {int n;cin >> n;cin.ignore();int m;cin >> m;// cin >> m;后直接调用getline, 相当于读取了一个换行符'\n'cin.ignore();vector<vector<int>> office(n);for (int i = 0; i < n; i++) {string line;getline(cin, line);istringstream iss(line);int k;while (iss >> k) {office[i].push_back(k);}}int i, j;cin >> i >> j;cin.ignore();string s;getline(cin, s);vector<int> relations;istringstream iss(s);int temp;while (iss >> temp) {relations.push_back(temp);}vector<vector<bool>> visited(n, vector<bool>(m, false));Solution sol;int result = sol.getmaxNum(office, visited, i, j, relations);cout << result;return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows SDK编程 --- 消息(3)

前置知识 一、消息的分类 1. 鼠标消息 处理与鼠标交互相关的事件&#xff0c;比如移动、点击和滚动等。例如&#xff1a; WM_MOUSEMOVE: 当鼠标在窗口客户区内移动时发送。WM_LBUTTONDOWN: 当用户按下鼠标左键时发送。WM_LBUTTONUP: 当用户释放鼠标左键时发送。WM_RBUTTOND…

C语言--基础面试真题

1、局部变量和静态变量的区别 普通局部变量和静态局部变量区别 存储位置&#xff1a; 普通局部变量存储在栈上 静态局部变量存储在静态存储区 生命周期&#xff1a; 当函数执行完毕时&#xff0c;普通局部变量会被销毁 静态局部变量的生命周期则是整个程序运行期间&#…

Oracle 21 C 安装详细操作手册,并配置客户端连接

Oracle 21 C 安装详细操作手册 Win 11 Oracle 21C 下载&#xff1a; Database Software Downloads | Oracle 中国 云盘共享 链接&#xff1a;https://pan.baidu.com/s/12XCilnFYyLFnSVoU_ShaSA 提取码&#xff1a;nfwc Oracle 21C 配置与登陆&#xff1a; 开始菜单 NetMa…

熊猫电竞赏金赛系统源码 APP+H5双端源码附搭建教程下载

熊猫电竞赏金系统简介 熊猫电竞赏金电竞系统 赏金赛源码&#xff0c;用户通过平台打比赛&#xff0c;赢了获得奖金奖励&#xff0c; 金币赛、赏金赛、vip赛等种赛事 可开王者荣耀、和平精英比赛 支持1v1、单排、双排组、战队排等多种比赛模式 支持QQ区、微信区 游戏玩的好…

Android——log的记忆

1.Java的 backtrace(堆栈log) 上述是一个空指针异常&#xff0c;问题出现在sgtc.settings&#xff0c;所以属于客户UI问题。 2.WindowManager(管理屏幕上的窗口和视图层次结构) 3.ActivityManager(管理应用程序生命周期和任务栈)

mac上VMware fusion net模式无法正常使用的问题

更新时间&#xff1a;2024年04月22日21:39:04 1. 问题 环境&#xff1a; intel芯片的macbook pro VMware fusion 13.5.1 无法将“Ethernet0”连接到虚拟网络“/dev/vmnet8”。在这里显示这个之后&#xff0c;应该是vmnet8的网段发生了冲突&#xff0c;所以导致无法正常使用…

text-shadow详解

text-shadow详解 属性定义及使用说明 text-shadow是CSS3中用于给文本添加阴影效果的属性。它允许您为文本内容添加一个或多个阴影&#xff0c;以增强视觉效果&#xff0c;创建立体感或装饰性文字外观。 语法 text-shadow: h-shadow v-shadow blur-radius spread-radius col…

yolov5_深度学习模型训练程序的暂停与恢复

问&#xff1a; 为什么要中断yolov5模型的训练&#xff1f; 答&#xff1a; 训练数据量大且过程漫长&#xff0c;电脑总要休息的嘛 简单直说&#xff1a; 1. 暂停 &#xff1a; 键盘输入&#xff1a; ctrl c这里以从第二次迭代中断为例&#xff1a; 2. 恢复模型训练 &am…

ChatGPT在线网页版(与GPT Plus会员完全一致)

ChatGPT镜像 今天在知乎看到一个问题&#xff1a;“平民不参与内测的话没有账号还有机会使用ChatGPT吗&#xff1f;” 从去年GPT大火到现在&#xff0c;关于GPT的消息铺天盖地&#xff0c;真要有心想要去用&#xff0c;途径很多&#xff0c;别的不说&#xff0c;国内GPT的镜像…

OpenCV-复数矩阵点乘ComplexMatrixDotMultiplication

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 需求说明 一般用到FFT&#xff0c;就涉及到复数的计算&#xff0c;为了便于调用&#xff0c;我自行封装了一个简单的复数矩阵点乘…

Linux I2C(二) - I2C软硬件架构

1&#xff0c;I2C的总线拓扑 2&#xff0c;I2C S/W topology linux kernel I2C framework使用如下的软件拓扑抽象I2C硬件&#xff08;我们可以一起领会一下其中的“设备模型”思想&#xff09;&#xff1a; 1&#xff09;platform bus&#xff08;/sys/bus/platform&#xff0…

空间转录组SODB数据库(补充)

SODB数据库 SODB facilitates comprehensive exploration of spatial omics data | Nature Methods https://db.cngb.org/stomics/ a–f&#xff0c; SODB的整体设计。六个六边形总结了SODB的六个特点。SODB包含各种类型的空间组学数据&#xff08;a&#xff09;&#xff0c…