KamaCoder 98. 所有可到达路径 + LC 797. All Paths From Source to Target

题目要求

给定一个有 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

思路 

首先要知道图应该怎么存储,然后是通过搜索的方法找出所有的边。

图的存储
邻接矩阵

本题有n个节点,节点标号从1开始,为了对其标号和下标,我们申请n+1*n+1这么大的二维数组。

vector<vector<int>> graph(n + 1, vector<int>(n + 1, 0));

输入m个边,构造方式如下:

while(m--) {cin >> s >> t;// 使用邻接矩阵,1表示节点s指向节点tgraph[s][t] = 1;
}
邻接表

采用数组+链表的形式来表示。

vector<list<int>> graph(n + 1); // 邻接表,list为C++里的链表,初始时没有申请空间,随用随取// 输入m个边
while(m--) {cin >> s >> t;// 使用邻接表,表示s —> t是相连的graph[s].push_back(t);
}
深度优先搜索

深搜三部曲:1.确认递归函数、参数, 2.确认终止条件,3.处理目前搜索节点出发的路径

1. 确认递归函数、参数

首先dfs函数一定要存一个图,用来遍历,需要存一个目前我们遍历的节点,定义为x。

还需要存储终点位置n,当x==n时表示到达了终点。

至于 单一路径 和 路径集合(答案)可以放在全局变量。

vector<vector<int>> result; // 收集符合条件的路径
vector<int> path; // 0节点到终点的路径
// x:目前遍历的节点
// graph:存当前的图
// n:终点
void dfs (const vector<vector<int>>& graph, int x, int n) {

 2. 确认终止条件

当目前遍历的节点为最后一个节点n的时候,就找到了一条从出发点到终止点的路径。

// 当前遍历的节点x,到达节点n
if (x == n) { // 找到符合条件的一条路径result.push_back(path);return;
}

3. 处理目前搜索节点出发的路径

接下来时走当前遍历节点x的下一个节点。

// 找到节点x指向哪些节点
for (int i = 1; i <= n; ++i) { // 遍历节点x链接的所有节点if (graph[x][i] == 1) { // 找到x指向的节点就是i// 将x所指向的节点加入到单一路径中path.push_back(i);// 进入下一层递归dfs(graph, i, n);// 回溯过程,撤销本次添加节点的操作path.pop_back();}
}
打印结果

注意结尾没有空格

// 输出结果
if (result.size() == 0) cout << -1 << endl;
for (const vector<int> &pa : result) {for (int i = 0; i < pa.size() - 1; ++i) { // 打印到倒数第二个cout << pa[i] << " ";}cout << pa[pa.size() - 1] << endl;
}

本题代码

C++邻接矩阵写法
#include <iostream>
#include <vector>
using namespace std;
vector<vector<int>> result;
vector<int> path;void dfs(const vector<vector<int>>& graph, int x, int n) {if (x == n) {result.push_back(path);return;}for (int i = 1; i <= n; ++i) {if (graph[x][i] == 1) {path.push_back(i);dfs(graph, i, n);path.pop_back();}}
}int main() {int n, m, s, t;cin >> n >> m;vector<vector<int>> graph(n + 1, vector<int>(n + 1, 0));for (int i = 1; i <= m; ++i) {cin >> s >> t;graph[s][t] = 1;}path.push_back(1); // 注意:无论什么路径都是从节点0(1)出发dfs(graph, 1, n);if (result.size() == 0) cout << -1 << endl;for (const vector<int> &pa : result) {for (int i = 0; i < pa.size() - 1; ++i) {cout << pa[i] << " ";}cout << pa[pa.size() - 1] << endl;}
}
C++邻接表写法
#include <iostream>
#include <vector>
#include <list>
using namespace std;
vector<vector<int>> result;
vector<int> path;void dfs(const vector<list<int>>& graph, int x, int n) {if (x == n) {result.push_back(path);return;}for (int i : graph[x]) {path.push_back(i);dfs(graph, i, n);path.pop_back();}
}int main() {int n, m, s, t;cin >> n >> m;vector<list<int>> graph(n + 1);while (m--) {cin >> s >> t;graph[s].push_back(t);}path.push_back(1); // 注意:无论什么路径都是从节点0(1)出发dfs(graph, 1, n);if (result.size() == 0) cout << -1 << endl;for (const vector<int> &pa : result) {for (int i = 0; i < pa.size() - 1; ++i) {cout << pa[i] << " ";}cout << pa[pa.size() - 1] << endl;}
}
Python邻接矩阵写法
def dfs(graph, x, n, path, result):if x == n:result.append(path.copy())returnfor i in range(1, n+1):if graph[x][i] == 1:path.append(i)dfs(graph, i, n, path, result)path.pop()def main():n, m = map(int, input().split())graph = [[0] * (n+1) for _ in range(n+1)]for _ in range(m):s, t = map(int, input().split())graph[s][t] = 1result = []dfs(graph, 1, n, [1], result)if not result:print(-1)else:for path in result:print(' '.join(map(str, path)))if __name__ == "__main__":main()
Python邻接表写法(注意collections.defaultdict的使用)
from collections import defaultdictresult = []
path = []def dfs(graph, x, n, path, result):if x == n:result.append(path.copy())returnfor i in graph[x]:path.append(i)dfs(graph, i, n, path, result)path.pop()def main():n, m = map(int, input().split())graph = defaultdict(list)for _ in range(m):s, t = map(int, input().split())graph[s].append(t)result = []dfs(graph, 1, n, [1], result)if not result:print(-1)else:for pa in result:print(' '.join(map(str, pa)))if __name__ == "__main__":main()

Leetcode 797. All Paths From Source to Target  

题目也是一道有向无环的图的求所有起点到终点的路径问题,区别在于不需要调整输入输出。(题目中的图已经给出了邻接表的存储形式)

C++
class Solution {
public:vector<int> path;vector<vector<int>> result;void dfs(const vector<vector<int>>& graph, int x, int n) {if (x == n) {result.push_back(path);return;}for (int i : graph[x]) {path.push_back(i);dfs(graph, i, n);path.pop_back();}}vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {path.push_back(0);dfs(graph, 0, graph.size() - 1);return result;    }
};
Python (注意列表是引用类型,后续修改会影响已经添加的路径,所以要用.copy())
class Solution:def dfs(self, graph, x, n, path, result):if (x == n):result.append(path.copy())returnfor i in graph[x]:path.append(i)self.dfs(graph, i, n, path, result)path.pop()def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:path = []result = []path.append(0)self.dfs(graph, 0, len(graph) - 1, path, result)return result

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Apache Nifi挂接MQTT与Kafka实践

目录 1. 说明&#xff1a; 2. 方案设计&#xff1a; 2.1 资源配置&#xff1a; 2.2 交互Topics: 3. 实现步骤 3.1 Nifi 桌面 3.2 MqttToKafka 3.2.1 配置 3.2.2 测试 3.2.3 结果 3.3 KafkaToMqtt 3.3.1 配置 3.3.1 测试 3.3.1 结果 ​编辑 4. 总结&#xff…

HAL STM32 SPI/ABZ/PWM方式读取MT6816磁编码器数据

HAL STM32 SPI/ABZ/PWM方式读取MT6816磁编码器数据 &#x1f4da;MT6816相关资料&#xff08;来自商家的相关资料&#xff09;&#xff1a; 资料&#xff1a;https://pan.baidu.com/s/1CAbdLBRi2dmL4D7cFve1XA?pwd8888 提取码&#xff1a;8888&#x1f4cd;驱动代码编写&…

计科录取75人!常州大学计算机考研考情分析!

常州大学&#xff08;Changzhou University&#xff09;&#xff0c;简称“常大”&#xff0c;位于江苏省常州市&#xff0c;是江苏省人民政府与中国石油天然气集团有限公司、中国石油化工集团有限公司及中国海洋石油集团有限公司共建的省属全日制本科院校&#xff0c;为全国深…

repo中的default.xml文件project name为什么一样?

文章目录 default.xml文件介绍为什么 name 是一样的&#xff0c;path 不一样&#xff1f;总结 default.xml文件介绍 在 repo 工具的 default.xml 文件中&#xff0c;定义了多个 project 元素&#xff0c;每个元素都代表一个 Git 仓库。 XML 定义了多个不同的 project 元素&…

Vue常用指令及其生命周期

作者&#xff1a;CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 目录 1.常用指令 1.1 v-bind 1.2 v-model 注意事项 1.3 v-on 注意事项 1.4 v-if / v-else-if / v-else 1.5 v-show 1.6 v-for 无索引 有索引 生命周期 定义 流程 1.常用指令 Vue当中的指令…

【MySQL进阶篇】锁:全局锁、表级锁以及行级锁

一、锁的概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中除传统的计算资源&#xff08;CPU、RAM、I/O&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须要解决的一个问题&am…

vs2019配置MySQL记录

vs2019配置MySQL记录 一、安装MySQL 参考&#xff1a;MySQL5.5.19的安装步骤 基本上就是一路默认安装就行。 二、验证 左下角打开MySQL 输入秘密能看到如下界面&#xff0c;即表示MySQL安装成功 三、安装vs2019的MySQL驱动 这里主要参考&#xff1a;Visual Studio 201…

MySQL练习03

题目 步骤 创建数据库 create database mydb11_stu; #创建 use mydb11_stu; #使用 创建表 student表 create table student( id int(10) not null unique primary key, name varchar(20) not null, sex varchar(4),birth year, department varchar(20), address var…

AR 眼镜之-充电动画定制-实现方案

目录 &#x1f4c2; 前言 AR 眼镜系统版本 充电动画 1. &#x1f531; 技术方案 1.1 方案介绍 1.2 实现方案 关机充电动画 亮屏/锁屏充电动画 2. &#x1f4a0; 关机充电动画 2.1 关机充电动画核心处理类与路径 2.2 实现细节 步骤一&#xff1a;1&#xff09;定制 …

从零开始学习网络安全渗透测试之基础入门篇——(二)Web架构前后端分离站Docker容器站OSS存储负载均衡CDN加速反向代理WAF防护

Web架构 Web架构是指构建和管理Web应用程序的方法和模式。随着技术的发展&#xff0c;Web架构也在不断演进。当前&#xff0c;最常用的Web架构包括以下几种&#xff1a; 单页面应用&#xff08;SPA&#xff09;&#xff1a; 特点&#xff1a;所有用户界面逻辑和数据处理都包含…

VSCode切换默认终端

我的VSCode默认终端为PowerShell&#xff0c;每次新建都会自动打开PowerShell。但是我想让每次都变为cmd&#xff0c;也就是Command Prompt 更改默认终端的操作方法如下&#xff1a; 键盘调出命令面板&#xff08;CtrlShiftP&#xff09;中,输入Terminal: Select Default Prof…

【记忆化搜索】【超详细】力扣3186. 施咒的最大总伤害

一个魔法师有许多不同的咒语。 给你一个数组 power &#xff0c;其中每个元素表示一个咒语的伤害值&#xff0c;可能会有多个咒语有相同的伤害值。 已知魔法师使用伤害值为 power[i] 的咒语时&#xff0c;他们就 不能 使用伤害为 power[i] - 2 &#xff0c;power[i] - 1 &…

记录安装android studio踩的坑 win7系统

最近在一台新电脑上安装android studio,报了很多错误&#xff0c;也是费了大劲才解决&#xff0c;发出来大家一起避免一些问题&#xff0c;找到解决方法。 安装时一定要先安装jdk&#xff0c;cmd命令行用java -version查当前的版本&#xff0c;没有的话&#xff0c;先安装jdk,g…

地形材质制作(能使地面湿润)

如图&#xff0c;创建一个材质并写以下逻辑 Landscape Layer Blend节点能使在地形模式绘制中有三个选择&#xff0c;根据以上逻辑&#xff0c;Red是原材质,Green是绿色材质也就是草&#xff0c;Blue为水&#xff08;这个我认为比较重要&#xff09; Blue的颜色最好为这个 这个节…

QEMU源码全解析 —— CPU虚拟化(11)

接前一篇文章: 本文内容参考: 《趣谈Linux操作系统》 —— 刘超,极客时间 《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社 《深度探索Linux系统虚拟化原理与实现》—— 王柏生 谢广军, 机械工业出版社 特此致谢! 前边几回又再次讲了一下VMX,本回开始讲解VCPU…

docker安装部署elasticsearch7.15.2

docker安装部署elasticsearch7.15.2 1.拉取es镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.15.2如果不想下载或者镜像拉去太慢可以直接下载文章上面的镜像压缩包 使用镜像解压命令 docker load -i elasticsearch-7-15-2.tar如下图所示就表示镜像解压成…

前端canvas——赛贝尔曲线

曲线之美&#xff0c;不在于曲线本身&#xff0c;而在于用的人。 所以就有了这期赛贝尔曲线。 新规矩&#xff0c;先上个GIT。 效果图 开局一张图&#xff0c;代码全靠编。 代码 画骨 先想着怎么画一个心形吧&#xff0c;等你想好了&#xff0c;就知道怎么画了。 首先就还…

HBuilder X中配置vue-cli项目和UI库

目录 一.前端项目结构 二.在HBuilder X中搭建vue-cli项目 1. 安装node.js前端环境 2. HBuilder X创建一个vue-cli项目 3. vue-cli项目结构 4. 如何运行前端项目 5. 创建组件 6. 组件路由(页面跳转) 6.1 创建router目录 6.2 使用路由 6.3 在main.js中配置路由 6.4 路…

Linux基础复习(二)

前言 本文介绍了一下Linux命令行基本操作及网络配置 一、 命令行提示含义 [当前用户主机名 工作目录]$ 若当前用户是root&#xff0c;则最后一个字符为# 否则&#xff0c;最后一个字符为$ 二、常用Linux命令及其解释 修改主机名 一般在创建一台主机后会使用hostname相关命…

分享4款国产好用的AI工具,提高工作学习效率

1.kimi 一款很多人都在夸的国产AI大模型&#xff0c;首先是免费使用的&#xff0c;其次它的智能化程度很高&#xff0c;也就是很“聪明”&#xff0c;亲测好用&#xff01; 它可以实时联网&#xff0c;通过网站实时访问并搜索信息。当你提出问题后&#xff0c;它能够立即检索…