【代码随想录训练营第42期 Day50打卡 - dfs入门 - 卡码网 98. 所有可达路径

本文主要是介绍【代码随想录训练营第42期 Day50打卡 - dfs入门 - 卡码网 98. 所有可达路径,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、dfs基础

二、模板题

题目:98. 所有可达路径

题目链接

题解:dfs+邻接矩阵

 三、小结


一、dfs基础

dfs是按照一个方向搜索到尽头再搜索其他方向。怎样实现对其他方向的搜索呢?我们可以通过回溯,撤销最后一步,再选择其他路线。 -- 回溯过程某种程度上也是递归的体现。所以,实现 dfs 的一个关键就是递归。

之前有了回溯的基础,其实可以发现回溯算法其实就是依靠 dfs 来实现。

这样我们就能得出 dfs 函数的基本模板(参考代码随想录):

void dfs(参数) {if (终止条件) {存放结果;return;}for (选择:本节点所连接的其他节点) {处理节点;dfs(图,选择的节点); // 递归回溯,撤销处理结果}
}

对于得到不同路径的问题,我们一般会采用两个数组来记录,一个存放所有路径,一个存放当前遍历的路径。

vector<vector<int>> ans;     // 符合条件的所有路径
vector<int> path;         // 当前遍历的路径

二、模板题

题目:98. 所有可达路径

题目链接

98. 所有可达路径 (kamacoder.com)

题目描述

给定一个有 n 个节点的有向无环图,节点编号从 1 到 n。请编写一个函数,找出并返回所有从节点 1 到节点 n 的路径。每条路径应以节点编号的列表形式表示。

输入描述

第一行包含两个整数 N,M,表示图中拥有 N 个节点,M 条边

后续 M 行,每行包含两个整数 s 和 t,表示图中的 s 节点与 t 节点中有一条路径

输出描述

输出所有的可达路径,路径中所有节点之间空格隔开,每条路径独占一行,存在多条路径,路径输出的顺序可任意。如果不存在任何一条路径,则输出 -1。

注意输出的序列中,最后一个节点后面没有空格! 例如正确的答案是 `1 3 5`,而不是 `1 3 5 `, 5后面没有空格!

输入示例

5 5
1 3
3 5
1 2
2 4
4 5

输出示例

1 3 5
1 2 4 5

提示信息

用例解释:

有五个节点,其中的从 1 到达 5 的路径有两个,分别是 1 -> 3 -> 5 和 1 -> 2 -> 4 -> 5。

因为拥有多条路径,所以输出结果为:

1 3 5
1 2 4 5

1 2 4 5
1 3 5
都算正确。

数据范围:

  • 图中不存在自环
  • 图中不存在平行边
  • 1 <= N <= 100
  • 1 <= M <= 500
题解:dfs+邻接矩阵

求不同路径的问题,一般通过 dfs 来实现。

这题出的很经典,我们需要的就是不断搜索找到不同的路径使得从起始位置到达中终止位置。

需要注意的是:

        1.这里用的节点 1 作为起始位置,那么初始化邻接矩阵,大小就应该为n+1;当然以节点 0 作为起始位置也可以,那么邻接矩阵大小就为 n ;

        2.标记相连的方式:邻接矩阵中 graph[s][t] = 1 -- 用 1 表示 s 与 t 相连。

深度优先搜索函数 dfs

        1.参数包括邻接矩阵 graph、当前节点 x 和目标节点 n。

        2.终止条件:如果当前节点 x 等于目标节点 n,则意味着找到了一条从起始节点到目标节点的路径。此时,将当前路径 path 添加到结果集 ans 中,并返回。

        3.遍历相邻节点:对于当前节点 x,遍历所有可能的相邻节点(从1到n)。

        4.如果节点 x 与节点 i 相连(即 graph[x][i] == 1),则执行以下步骤:

                将节点 i 添加到当前路径 path 中;

                递归调用 dfs 函数,从节点 i (与 x 相连接的节点)开始继续深度优先搜索;

                在递归返回后,将节点 i 从路径 path 中移除,以实现回溯。

代码如下(其实就是 dfs 模板的应用):

#include<bits/stdc++.h>
using namespace std;vector<vector<int>> ans;        // 存放符合条件的路径 -- 存放结果
vector<int> path;           // 起始位置(节点1)到终点的路径void dfs (const vector<vector<int>>& graph, int x, int n) { if (x == n) {       // 终止条件:当前遍历的节点 x 到达节点 n,说明找到符合条件的一条路径ans.push_back(path);        //当前路径存入 ansreturn;}for (int i = 1; i <= n; i++) {      // 遍历节点 x 连接的所有节点if (graph[x][i] == 1) {         // 找到 x 连接的节点path.push_back(i);      // 遍历到的节点加入到路径中来dfs(graph, i, n);       // 进入下一层递归 -- 从当前 x 连接的 i 开始path.pop_back();        // 回溯,撤销本节点}}
}int main() {int n, m, s, t;cin >> n >> m;vector<vector<int>> graph(n + 1, vector<int>(n + 1, 0));        // 初始化邻接矩阵,大小为n+1,因为节点编号从1开始while (m--) {cin >> s >> t;graph[s][t] = 1;    // 使用邻接矩阵表示无线图,1 表示 s 与 t 是相连的}path.push_back(1);         // 将起始节点1加入到路径中 -- 后续dfs操作并不添加起始节点1dfs(graph, 1, n);        // 从节点1开始深度优先搜索if (ans.size() == 0) {          // 没有找到任何路径cout<<"-1"<<endl;}for (const vector<int> &p : ans) {              // 这里的 p 用来遍历 ans 的各个元素 -- 每个元素都是一条路径 path,需单独将这些路径打印for (int i = 0; i < p.size() - 1; i++) {       // 注意:当前路径最后一个元素后无空格 -- 遍历范围 0 -- size-2cout << p[i] << " ";}cout << p[p.size() - 1]  << endl;        // 将每条路径最后一个元素单独提出来,从而防止最后结果多出一个空格}
}

 三、小结

今天来到图论章节打卡的第一天,这一类问题并不简单,后边会继续进行相关内容的练习和打卡,希望终能有所收获。

这篇关于【代码随想录训练营第42期 Day50打卡 - dfs入门 - 卡码网 98. 所有可达路径的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1137706

相关文章

Spring WebClient从入门到精通

《SpringWebClient从入门到精通》本文详解SpringWebClient非阻塞响应式特性及优势,涵盖核心API、实战应用与性能优化,对比RestTemplate,为微服务通信提供高效解决... 目录一、WebClient 概述1.1 为什么选择 WebClient?1.2 WebClient 与

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三

从入门到精通详解LangChain加载HTML内容的全攻略

《从入门到精通详解LangChain加载HTML内容的全攻略》这篇文章主要为大家详细介绍了如何用LangChain优雅地处理HTML内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录引言:当大语言模型遇见html一、HTML加载器为什么需要专门的HTML加载器核心加载器对比表二

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

从入门到进阶讲解Python自动化Playwright实战指南

《从入门到进阶讲解Python自动化Playwright实战指南》Playwright是针对Python语言的纯自动化工具,它可以通过单个API自动执行Chromium,Firefox和WebKit... 目录Playwright 简介核心优势安装步骤观点与案例结合Playwright 核心功能从零开始学习

MySQL进行数据库审计的详细步骤和示例代码

《MySQL进行数据库审计的详细步骤和示例代码》数据库审计通过触发器、内置功能及第三方工具记录和监控数据库活动,确保安全、完整与合规,Java代码实现自动化日志记录,整合分析系统提升监控效率,本文给大... 目录一、数据库审计的基本概念二、使用触发器进行数据库审计1. 创建审计表2. 创建触发器三、Java

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

从入门到精通MySQL联合查询

《从入门到精通MySQL联合查询》:本文主要介绍从入门到精通MySQL联合查询,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下... 目录摘要1. 多表联合查询时mysql内部原理2. 内连接3. 外连接4. 自连接5. 子查询6. 合并查询7. 插入查询结果摘要前面我们学习了数据库设计时要满

从入门到精通C++11 <chrono> 库特性

《从入门到精通C++11<chrono>库特性》chrono库是C++11中一个非常强大和实用的库,它为时间处理提供了丰富的功能和类型安全的接口,通过本文的介绍,我们了解了chrono库的基本概念... 目录一、引言1.1 为什么需要<chrono>库1.2<chrono>库的基本概念二、时间段(Durat