当前位置: 首页 > 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;…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

JDK 17 新特性

#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持&#xff0c;不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的&#xff…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA

浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求&#xff0c;本次涉及的主要是收费汇聚交换机的配置&#xff0c;浪潮网络设备在高速项目很少&#xff0c;通…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...