当前位置: 首页 > news >正文

C++ 算法学习——1.3 双向深度优先搜索

双向深度优先搜索(Bidirectional Depth-First Search)是一种图搜索算法,旨在通过从起始节点和目标节点同时开始,沿着深度优先搜索的路径向前探索,以减少搜索空间并提高搜索效率。

1. 基本原理

  • 双向深度优先搜索同时从起始节点和目标节点开始搜索,通过交替地在两个方向上进行深度优先搜索,直到两个搜索路径相遇。

2. 算法步骤

  1. 初始化两个空的栈,一个用于从起始节点开始的搜索,另一个用于从目标节点开始的搜索。
  2. 将起始节点和目标节点分别推入两个栈。
  3. 从两个栈中分别出栈一个节点,进行如下操作:
    • 标记节点为已访问。
    • 检查当前节点是否在两个搜索方向上相遇,如果相遇则搜索结束。
    • 否则,对当前节点的未访问邻居节点进行处理:
      • 对于起始节点搜索方向,将未访问的邻居节点推入起始栈。
      • 对于目标节点搜索方向,将未访问的邻居节点推入目标栈。
  4. 重复步骤3,直到两个栈中的节点相遇或者两个栈都为空。

3. 优缺点

  • 优点
    • 相较于单向深度优先搜索,双向深度优先搜索在搜索空间较大时能够更快地找到目标节点。
  • 缺点
    • 需要额外的内存空间来维护两个搜索方向的栈。
    • 在特定情况下可能会比单向搜索更慢,例如在目标节点附近的情况。

代码示例(邻接表表示的图):

#include <iostream>
#include <vector>
#include <stack>
#include <unordered_set>using namespace std;// 无权图的邻接表表示
vector<vector<int>> graph;// 双向深度优先搜索函数
bool bidirectionalDFS(int start, int target) {stack<int> startStack, targetStack;unordered_set<int> startVisited, targetVisited;startStack.push(start);targetStack.push(target);while (!startStack.empty() && !targetStack.empty()) {int currentStart = startStack.top();int currentTarget = targetStack.top();startStack.pop();targetStack.pop();startVisited.insert(currentStart);targetVisited.insert(currentTarget);// 检查是否相遇if (startVisited.count(currentTarget) || targetVisited.count(currentStart)) {cout << "Nodes met at: " << (startVisited.count(currentTarget) ? currentTarget : currentStart) << endl;return true;}//对于std::unordered_set和std::unordered_map,count函数会返回1(存在)或0(不存在)。// 处理邻居节点for (int neighbor : graph[currentStart]) {if (!startVisited.count(neighbor)) {startStack.push(neighbor);}}for (int neighbor : graph[currentTarget]) {if (!targetVisited.count(neighbor)) {targetStack.push(neighbor);}}}cout << "Nodes did not meet." << endl;return false;
}

代码示例(矩阵模样,起点坐标begina,beginb,目标点坐标enda,endb):

#include <iostream>
#include <stack>
#include <unordered_set>
using namespace std;
int n,m;
char** board;
void showcurboard()
{for(int i=0;i<n;i++){for(int j=0;j<m;j++)cout<<board[i][j];cout<<endl;}
}
struct PairHash {template <class T1, class T2>std::size_t operator () (const std::pair<T1, T2> &pair) const {auto hash1 = std::hash<T1>{}(pair.first);auto hash2 = std::hash<T2>{}(pair.second);return hash1 ^ hash2;}
};
// 双向深度优先搜索函数
bool bidirectionalDFS(int begina, int beginb, int enda, int endb) {stack<pair<int, int>> startStack, targetStack;unordered_set<pair<int, int>,PairHash> startVisited;unordered_set<pair<int, int>,PairHash> targetVisited;startStack.push({begina, beginb});targetStack.push({enda, endb});while (!startStack.empty() && !targetStack.empty()) {auto currentStart = startStack.top();auto currentTarget = targetStack.top();startStack.pop();targetStack.pop();startVisited.insert(currentStart);targetVisited.insert(currentTarget);// 检查是否相遇if (startVisited.count(currentTarget) || targetVisited.count(currentStart)) {return true;}// 处理邻居节点int dirs[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};for (auto dir : dirs) {int nextStartA = currentStart.first + dir[0];int nextStartB = currentStart.second + dir[1];if (nextStartA >= 0 && nextStartA < n && nextStartB >= 0 && nextStartB < m &&!startVisited.count({nextStartA, nextStartB})) {startStack.push({nextStartA, nextStartB});}int nextTargetA = currentTarget.first + dir[0];int nextTargetB = currentTarget.second + dir[1];if (nextTargetA >= 0 && nextTargetA < n && nextTargetB >= 0 && nextTargetB < m &&!targetVisited.count({nextTargetA, nextTargetB})) {targetStack.push({nextTargetA, nextTargetB});}}}return false;
}int main()
{cin>>n>>m;board=new char*[n];for(int i=0;i<n;i++){board[i]=new char[m];for(int j=0;j<m;j++) cin>>board[i][j];}showcurboard();return 0;
}

P1. b3625迷宫寻路 

#include <iostream>
#include <stack>
#include <unordered_set>
using namespace std;
int n,m;
char** board;
void showcurboard()
{for(int i=0;i<n;i++){for(int j=0;j<m;j++)cout<<board[i][j];cout<<endl;}
}
struct PairHash {template <class T1, class T2>std::size_t operator () (const std::pair<T1, T2> &pair) const {auto hash1 = std::hash<T1>{}(pair.first);auto hash2 = std::hash<T2>{}(pair.second);return hash1 ^ hash2;}
};
// 双向深度优先搜索函数
bool bidirectionalDFS(int begina, int beginb, int enda, int endb) {stack<pair<int, int>> startStack, targetStack;unordered_set<pair<int, int>,PairHash> startVisited;unordered_set<pair<int, int>,PairHash> targetVisited;startStack.push({begina, beginb});targetStack.push({enda, endb});while (!startStack.empty() && !targetStack.empty()) {auto currentStart = startStack.top();auto currentTarget = targetStack.top();startStack.pop();targetStack.pop();startVisited.insert(currentStart);targetVisited.insert(currentTarget);// 检查是否相遇if (startVisited.count(currentTarget) || targetVisited.count(currentStart)) {return true;}// 处理邻居节点int dirs[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};for (auto dir : dirs) {int nextStartA = currentStart.first + dir[0];int nextStartB = currentStart.second + dir[1];if (nextStartA >= 0 && nextStartA < n && nextStartB >= 0 && nextStartB < m &&!startVisited.count({nextStartA, nextStartB})&&board[nextStartA][nextStartB]=='.') {startStack.push({nextStartA, nextStartB});}int nextTargetA = currentTarget.first + dir[0];int nextTargetB = currentTarget.second + dir[1];if (nextTargetA >= 0 && nextTargetA < n && nextTargetB >= 0 && nextTargetB < m &&!targetVisited.count({nextTargetA, nextTargetB})&&board[nextTargetA][nextTargetB]=='.') {targetStack.push({nextTargetA, nextTargetB});}}}return false;
}int main()
{cin>>n>>m;board=new char*[n];for(int i=0;i<n;i++){board[i]=new char[m];for(int j=0;j<m;j++) cin>>board[i][j];}//showcurboard();bool ans=bidirectionalDFS(0,0,n-1,m-1);if(ans) cout<<"Yes";else cout<<"No";return 0;
}

相关文章:

C++ 算法学习——1.3 双向深度优先搜索

双向深度优先搜索&#xff08;Bidirectional Depth-First Search&#xff09;是一种图搜索算法&#xff0c;旨在通过从起始节点和目标节点同时开始&#xff0c;沿着深度优先搜索的路径向前探索&#xff0c;以减少搜索空间并提高搜索效率。 1. 基本原理 双向深度优先搜索同时从…...

Artistic Oil Paint 艺术油画着色器插件

只需轻轻一点&#xff0c;即可将您的视频游戏转化为艺术品&#xff01;&#xff08;也许更多…&#xff09;。 ✓ 整个商店中最可配置的选项。 ✓ 六种先进算法。 ✓ 细节增强算法。 ✓ 完整的源代码&#xff08;脚本和着色器&#xff09;。 ✓ 包含在“艺术包”中。 &#x1f…...

记一次left join联表查询的索引失效场景

结论&#xff1a;关联表的列的字符集不一致导致的 场景&#xff1a;user_t&#xff08;用户表&#xff09;、org_t&#xff08;机构表&#xff09;&#xff0c;user_t的org_id和org_t的id是一对一关系 1.explain发现org_t表未走索引&#xff0c;但是org_t的id字段默认存在主键…...

从零到一:前端开发者学习 Cocos Creator 的全攻略

大家好&#xff0c;我是小蜗牛。 作为一名前端开发者&#xff0c;掌握 Cocos Creator 是一个非常有趣且充满潜力的技能。Cocos Creator 是一款免费开源的游戏开发引擎&#xff0c;它的工作流和前端开发非常相似&#xff0c;因此前端开发者可以较快上手&#xff0c;并通过开发小…...

JavaWeb 19 AJAX

目录 一、什么是AJAX 同步交互和异步交互 同步交互 异步交互 Ajax工作原理 Ajax实现方式 原生JavaScript方式进行ajax(了解)&#xff1a; "我就是希望你好&#xff0c;就像很多人希望我好一样&#xff0c;特别简单&#xff0c;特别真挚。也不为了什么&#xff0c;就是希望…...

element plus中menu菜单技巧

我在使用element plus的menu&#xff08;侧边栏&#xff09;组件的过程中遇到了一些问题&#xff0c;就是menu编写样式和路由跳转&#xff0c;下面给大家分享以下&#xff0c;我是怎么解决的。 1.页面效果 我要实现的网站布局是这样的&#xff1a; 侧边栏折叠以后的效果&#…...

数据结构-贪心算法笔记

前言&#xff1a;贪心无套路&#xff0c;狠狠刷就完事 分发饼干 455. 分发饼干 - 力扣&#xff08;LeetCode&#xff09; class Solution {/*** 找出最多有多少个孩子可以得到糖果。** param g 一个数组&#xff0c;表示每个孩子对糖果大小的满意度。* param s 一个数组&…...

基于SpringBoot的在线汽车票预订平台

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理汽车票网上预订系统的相关信息成为必然。开…...

ubuntu 安装nginx

sudo apt-get update sudo apt-get install nginx sudo nginx -vsudo systemctl status nginx sudo systemctl start nginx sudo systemctl stop nginx sudo systemctl restart nginx#浏览器输入&#xff1a;http://192.168.31.181/#查看文件结构 cd /etc/nginx sudo cp nginx.…...

fanuc远程PNS启动

参考 PNS & RSR区别 前者是8bit255 个程序 后者是bitN对应8个程序...

使用 Spring 框架构建 MVC 应用程序:初学者教程

Spring Framework 是一个功能强大、功能丰富且设计精良的 Java 平台框架。它提供了一系列编程和配置模型&#xff0c;旨在简化和精简 Java 中健壮且可测试的应用程序的开发过程。 人们常说 Java 太复杂了&#xff0c;构建简单的应用程序需要很长时间。尽管如此&#xff0c;Jav…...

集成Spring Security详解

集成Spring Security详解 一、Spring Security简介 Spring Security是一个功能强大且高度可定制的身份验证和访问控制框架&#xff0c;它专注于为Java应用程序提供全面的安全解决方案。作为Spring项目的一部分&#xff0c;Spring Security继承了Spring框架的灵活性和可扩展性…...

Kettle9.4支持Clickhouse数据源插件开发以及性能测试

前言 最近业务这边有个指标需要用到大数据这边的列式数据库进行处理&#xff0c;由于kettle不支持clickhouse数据源驱动&#xff0c;这里查了一下网上的相关资料&#xff0c;发现了一些别人开发好的驱动包&#xff0c;下载下来后使用效果不尽人意。总结下来有以下几个问题&…...

微信支付V3 yansongda/pay 踩坑记录

Pay - 让支付开发更简单 | Pay 使用laravel 8框架 2.1 报错 Parse [mch_public_cert_path] Serial Number Error 是mch_secret_cert&#xff0c;mch_public_cert_path配置错误 2.2 报错 Get Wechat Public Cert Error 是mch_secret_key配置错误 #正确 Pay::config(config(w…...

AndroidStudio实验报告——实验一、二

目录 实验一&#xff1a; AS安装与安卓环境搭建 一、实验目标 二、实验内容 &#xff08;一&#xff09;Android Studio安装 &#xff08;二&#xff09;JDK安装与配置 &#xff08;三&#xff09;Android SDK安装与配置 三、实验结果&#xff1a;&#xff08;实…...

Nginx超简洁知识:负载均衡-反向代理,动静分离,配置文件

首先介绍一下为什么需要nginx&#xff1f; 在低并发场景下&#xff08;也就是用户量特别少的情况下&#xff09;&#xff0c;我们只需要部署一台服务器就能满足用户数量少的需求。 但是如果用户量逐渐增多&#xff0c;只有一台服务器是不够的。于是我们需要部署多台服务器。 …...

云手机:社交平台运营的热门工具

随着互联网的飞速发展&#xff0c;社交平台已经成为企业推广和营销的核心渠道。传统的运营方式已经无法满足高效运营的需求&#xff0c;而云手机作为新兴工具&#xff0c;逐渐成为社交平台运营的前沿趋势。本文将深入分析云手机如何优化社交平台的运营流程&#xff0c;助力企业…...

iptables限速规则

环境&#xff1a; iptables服务器&#xff1a;172.16.12.33 client&#xff1a;192.168.1.2 1、在防火墙上配置客户端的下载速度是1M/s &#xff08;1个包是1.3KB&#xff09; #限速客户端每秒的下载速度是1024KB&#xff0c;超出限制的流量就丢弃 [rootiptables-172-16-12-…...

易泊车牌识别:海外车牌快速定制,开启智能识别新时代

在当今数字化快速发展的时代&#xff0c;车牌识别技术已经成为了智能交通系统中不可或缺的一部分。而在众多车牌识别解决方案中&#xff0c;易泊车牌识别系统以其卓越的性能和独特的优势脱颖而出&#xff0c;尤其是在海外车牌快速定制方面&#xff0c;更是展现出了强大的实力。…...

同一个交换机不同vlan的设备为什么不能通信

在同一个交换机上&#xff0c;不同 VLAN 的设备不能直接通信&#xff0c;这是因为 VLAN&#xff08;虚拟局域网&#xff09;通过在数据链路层&#xff08;OSI 第2层&#xff09;对设备进行逻辑隔离&#xff0c;将不同 VLAN 的设备视为属于不同的网络。具体原因如下&#xff1a;…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

有限自动机到正规文法转换器v1.0

1 项目简介 这是一个功能强大的有限自动机&#xff08;Finite Automaton, FA&#xff09;到正规文法&#xff08;Regular Grammar&#xff09;转换器&#xff0c;它配备了一个直观且完整的图形用户界面&#xff0c;使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...