图论基础知识 深度搜索(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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RT-Thread-12c设备

半双工&#xff1a;可以发也可以收&#xff0c;但不能收发 双向双工&#xff1a;D端既有Rx也有Tx&#xff0c;既可以读也可以写&#xff0c;可以同时收发 I2C&#xff08;Inter Integrated Circuit&#xff09;总线是 PHILIPS 公司开发的一种半双工、双向二线制同步串行总线。…

WIN10专业版如何备份系统?

1.打开控制面板 2.单击系统和安全性 3.单击备份和还原&#xff08;Windows 7&#xff09; 4.单击左侧面板中的创建系统映像 5.可以选择要在哪里保存备份映像&#xff1a;外部硬盘驱动器或DVD。我建议使用前者&#xff0c;即使您的计算机具有DVD-RW驱动器&#xff0c;也要将外…

分布式基础

摘要&#xff1a;汇总整理部分概念和理论... 1. 什么是分布式 利用物理结构形成多个自治的处理元素&#xff0c;不共享主内存&#xff0c;但是通过发送信息合作。 — Leslie Lamport 2. 分布式的作用 单体应用的问题 速度变慢、熟悉项目工作量太大、耦合严重、合并代码冲突多…

虚拟化及Docker基础

一、虚拟化 1.1 云端 1.2 云计算服务模式分层 1.3 虚拟化架构 1.3.1 寄居架构 1.3.2 原生架构 1.4 虚拟化产品 1.4.1 仿真虚拟化产品&#xff08;对系统硬件没有要求&#xff0c;性能最低&#xff09; 1.4.2 半虚拟化 &#xff08;虚拟机可以使用真机物理机&#xff09…

如何训练一个大语言模型(LLMs)

目录 前言大语言模型 Vs机器学习模型训练过程步骤1&#xff1a;数据策划&#xff08;Data Curation)步骤2&#xff1a;格式化与预处理步骤3&#xff1a;训练模型步骤4&#xff1a;模型评估 LLM Leaderboard[LLM Leaderboard 2024](https://www.vellum.ai/llm-leaderboard)[Open…

ubuntu22.04 CH340/CH34x 驱动安装

CH34x驱动地址&#xff1a;CH341SER_LINUX.ZIP - 南京沁恒微电子股份有限公司 1、卸载旧驱动&#xff08;如果存在&#xff09; sudo rmmod ch341.ko 2、解压进入 driver 目录 unzip CH341SER_LINUX.ZIP cd CH341SER_LINUX/driver 3、编译 make 可能错误&#xff1a; make[1]…

搜索策略相关内容

相关参考链接: 理解三个指标&#xff1a;Recall、NDCG、RMSE Ranking算法评测指标之 CG、DCG、NDCG 搜索的评价指标DCG 一、搜索方面的内容 搜索的结构框架 大致可以分为四个部分&#xff1a;搜集、分析、索引和查询。 信息搜集&#xff1a;利用爬虫等技术实时更新、自动获…

震惊!!!OB 居然也卷 OLAP

作者 | JiekeXu 来源 |公众号 JiekeXu DBA之路&#xff08;ID: JiekeXu_IT&#xff09; 如需转载请联系授权 | (个人微信 ID&#xff1a;JiekeXu_DBA) 大家好&#xff0c;我是 JiekeXu,江湖人称“强哥”&#xff0c;很高兴又和大家见面了,今天和大家一起来看看 OB 也卷 OLAP 了…

【MySQL 数据宝典】【线程模型】-IO Thread、Puge Thread介绍

一、 线程模型 多线程模型 InnoDB存储引擎采用多线程模型&#xff0c;其后台运行多个不同的后台线程&#xff0c;每个线程负责处理特定的任务。 后台线程功能 刷新内存池数据&#xff1a; 后台线程负责定期刷新内存池中的数据&#xff0c;以确保缓冲池中的内存缓存保持最新的…

FebHost:科技企业如何规划并注册.AI域名?

为确保企业使用.AI域名的方式准确反映其对人工智能技术的关注&#xff0c;企业应考虑以下步骤&#xff1a; 了解法律和合规要求&#xff1a; 第一步是了解与 .AI 域名相关的独特法律和合规要求。由于.AI域名源于安圭拉&#xff0c;企业必须遵守安圭拉的限制和法律规定。这包括…

搭建MySQL主从结构时的问题

说明&#xff1a;记录搭建MySQL主从结构时遇到的两个问题&#xff1b; 问题一&#xff1a;连接主节点失败 搭建完成后从节点查看状态如下&#xff1a; 错误&#xff1a;error connecting to master admin主机IP - retry-time: 60 retries: 712 message: Host 主机IP is block…

通配符/泛域名SSL证书可以保护多少个域名

通配符/泛域名SSL证书&#xff0c;他可以保护一个主域名和无限个子域名。我们需要了解什么是通配符/泛域名SSL证书。这种证书是一种特殊的数字证书&#xff0c;它允许一个单一的SSL证书被安装在多个服务器上。这是通过使用通配符&#xff08;*&#xff09;来实现的&#xff0c;…

关于开设RT-DETR专栏及更新内容的一些说明

​ 专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;助力高效涨点&#xff01;&#xff01;&#xff01; 专栏介绍 YOLOv9作为最新的YOLO系列模型&#xff0c;对于做目标检测的同学是必不可少的。本专栏将针对2024年最新推出的YOLOv9检测模型&#xff0…

项目优化11

QT多线程 发送数据不在主线程里面发送了&#xff0c;用信号槽机制&#xff0c;让数据移动到另一个线程里面去发送 多线程发送视频帧&#xff1a;kernel类里&#xff1a; .cpp

【面试经典 150 | 数组】整数转罗马数字

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;模拟 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行回顾…

人工智能论文GPT-3(5):2020.5 Language Models are Few-Shot Learners;总结

6 更广泛的影响 语言模型对社会具有广泛的有益应用&#xff0c;包括代码和写作自动完成、语法辅助、游戏叙事生成、提高搜索引擎响应速度和回答问题等。但它们也可能具有潜在的有害应用。GPT-3 提高了文本生成质量和适应性&#xff0c;使得相较于较小的模型更难将合成文本与人…

AI自动生成PPT文档 aippt的API介绍文档

官方链接直达&#xff01; 产品介绍​ 能力介绍​ AiPPT 是一款智能生成演示幻灯片的在线工具。专业设计团队打造海量模板资源&#xff0c;输入标题即可轻松生成完整的PPT。同时 AiPPT 支持导入多格式文档一键生成 PPT&#xff0c;让 PPT 创作更加高效。聚焦于内容&#xff0…

夜鸦国际服账号验证怎么办 夜鸦国际服账号认证的详细教程

夜鸦国际服账号验证怎么办 夜鸦国际服账号认证的详细教程 今天为大家带来的是《夜鸦》这款游戏&#xff0c;游戏背景是基于13世纪欧洲背景的MMORPG游戏&#xff0c;这款游戏以其沉浸式的游戏体验和流畅的打斗为特色。玩家可以选择战士、剑士、猎人或女巫等角色&#xff0c;体验…

Tensorflow AutoGraph 的作用和功能

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ TensorFlow AutoGraph 是 TensorFlow 中的一个重要特性&#xff0c;它允许开发者使用普通的 Python 语法编写高效的 TensorFlow 图&#xff08;graph&#xff09;。这意味着开发者可以利用 Python 的易…

(六)小案例银行家应用程序-删除账号-findindex方法

findindex方法和find方法非常类似&#xff0c;只不过findindex顾名思义&#xff0c;他返回的是index&#xff1b; ● 下面我们使用删除账号的功能来学习一下findindex的 ● 当用户登录成功之后&#xff0c;可以在下方输入自己的用户名和密码&#xff0c;然后提交&#xff0c…