代码随想录算法训练营第五十天 | 98. 所有可达路径

news2024/12/24 0:13:25

目录

98. 所有可达路径

思路

图的存储

邻接矩阵

         邻接表

深度优先搜索

1.确认递归函数,参数

2.确认终止条件

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

方法一: 邻接矩阵写法

方法二:邻接表写法


98. 所有可达路径

  • 题目链接:卡码网题目链接(ACM模式)
  • 文章讲解:代码随想录 

【题目描述】

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

思路

图的存储

在图论理论基础篇 中我们讲到了 两种 图的存储方式:邻接表 和 邻接矩阵。

本题我们将带大家分别实现这两个图的存储方式。

邻接矩阵

邻接矩阵 使用 二维数组来表示图结构。 邻接矩阵是从节点的角度来表示图,有多少节点就申请多大的二维数组。

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

邻接表

邻接表 使用 数组 + 链表的方式来表示。 邻接表是从边的数量来表示图,有多少边 才会申请对应大小的链表。

邻接表的构造相对邻接矩阵难理解一些。

我在 图论理论基础篇 举了一个例子:

这里表达的图是:

  • 节点1 指向 节点3 和 节点5
  • 节点2 指向 节点4、节点3、节点5
  • 节点3 指向 节点4
  • 节点4指向节点1

我们需要构造一个数组,数组里的元素是一个链表。

深度优先搜索

本题是深度优先搜索的基础题目,关于深搜我在图论深搜理论基础 已经有详细的讲解,图文并茂。

关于本题我会直接使用深搜三部曲来分析,如果对深搜不够了解,建议先看 图论深搜理论基础。

深搜三部曲来分析题目:

1.确认递归函数,参数

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

还需要存一个n,表示终点,我们遍历的时候,用来判断当 x==n 时候 标明找到了终点。

(其实在递归函数的参数 不容易一开始就确定了,一般是在写函数体的时候发现缺什么,参加就补什么)至于 单一路径 和 路径集合 可以放在全局变量。

2.确认终止条件

什么时候我们就找到一条路径了?

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

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

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

首先是要找到 x节点指向了哪些节点呢? 遍历方式是这样的:

for i in range(1,n+1): # 遍历节点x链接的所有节点
    if graph[x][i] == 1: # 找到 x指向的节点,就是节点i
    

接下来就是将 选中的x所指向的节点,加入到 单一路径来。

path.append(i) # 遍历到的节点加入到路径中来

进入下一层递归

def dfs(graph, i, n) : # 进入下一层递归

最后就是回溯的过程,撤销本次添加节点的操作。

为什么要有回溯,我在图论深搜理论基础 也有详细的讲解。

方法一: 邻接矩阵写法

def dfs(graph,x,n,path,result):
    if x == n:
        result.append(path[:])
        return
    for 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 i in range(m):
        s,t = map(int,input().split())
        graph[s][t] = 1

    result = []

    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()

方法二:邻接表写法

from collections import defaultdict

result = []  # 收集符合条件的路径
path = []  # 1节点到终点的路径

def dfs(graph, x, n):
    if x == n:  # 找到符合条件的一条路径
        result.append(path.copy())
        return
    for i in graph[x]:  # 找到 x指向的节点
        path.append(i)  # 遍历到的节点加入到路径中来
        dfs(graph, i, n)  # 进入下一层递归
        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)

    path.append(1)  # 无论什么路径已经是从1节点出发
    dfs(graph, 1, n)  # 开始遍历

    # 输出结果
    if not result:
        print(-1)
    for path in result:
        print(' '.join(map(str, path)))

if __name__ == "__main__":
    main()

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

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

相关文章

2024年第十五届蓝桥杯青少组国赛撞期GESP认证、放弃那个?

昨天蓝桥杯青少组官网发布了速查|第十五届蓝桥杯大赛青少组省赛成绩查询&#xff0c;首先恭喜2024年蓝桥杯青少组省赛一等奖的同学晋级蓝桥杯大赛青少组国赛&#xff0c;蓝桥杯青少组国赛的时间为2024年9月7日&#xff0c;CCF GESP编程能力等级认证也在同一天开始&#xff0c;同…

Linux工具: 查询各种系统数据库和服务的linux命令getent详解

目录 一、概述 二、用法 1、基本语法 &#xff08;1&#xff09;database &#xff08;2&#xff09;key 2、常见的数据库类型 3、获取帮助 三、示例 1. 查询用户账号信息 2. 列出所有用户 3. 查询特定组的信息 4. 列出所有组 5. 查询主机名和 IP 地址映射 6. 列…

vue3中openlayers绘制多个Overlay

项目需求是要在地图上显示多个div&#xff0c;之前使用Overlay绘制单个显示正常&#xff0c;结果绘制多个的时候就显示一个&#xff0c;不过也解决了&#xff0c;下面我就把核心代码贴一下&#xff0c;如果有什么问题可以留言&#xff0c;我就是提供一个思路。 效果图 上面图片…

昂科烧录器支持Fortior Tech峰岹科技的电机驱动专用芯片FU6812V

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中Fortior Tech峰岹科技的高性能电机驱动专用芯片FU6812V已经被昂科的通用烧录平台AP8000所支持。 FU6812V是一款集成电机控制引擎(ME)和8051内核的高性能电机驱动专用芯片&…

Nginx性能调优

为什么是Nginx而不是apache&#xff1f; 轻量级&#xff0c;同样起web服务器&#xff0c;比apache占用更少的内存资源静态处理&#xff0c;Nginx静态处理性能比apache高3倍以上抗并发&#xff0c;Nginx处理请求时异步非阻塞的&#xff0c;而apache则是阻塞型的&#xff0c;在高…

代替STM32L010 STM32G030 CMS8S6990 STM8S003的芯片CW32L010

CW32L010作为一款可以代替STM32L010 STM32G030 CMS8S6990 STM8S003部分型号可以兼容的芯片&#xff0c;其功能上能够和它们相匹配&#xff0c;并且在功能更优秀&#xff0c;其芯片特点在于超低功耗&#xff0c;高精度ADC和主频最高可达到48MHz。 CW32L010是基于eFlash的单芯片低…

AutosarMCAL开发——基于EB Gpt驱动

目录 1.Gpt原理2.EB配置以及接口应用2.1 EB配置2.2 接口应用 3.总结 1.Gpt原理 autosar GPT模块&#xff08;General Purpose Timer&#xff0c;通用定时器&#xff09;主要用于汽车ECU中的时间测量、计数和产生定时中断。它支持单次性和周期性定时器&#xff0c;可以在达到预…

结合Scrapy和无限住宅代理进行大规模的数据抓取方案

在大规模数据抓取的过程中&#xff0c;如何高效、安全地获取数据是一个关键问题。Scrapy作为一种强大的爬虫框架&#xff0c;能够帮助开发者快速抓取和处理网站数据。而无限住宅代理则提供了全球范围内的IP地址&#xff0c;极大地提升了数据抓取的效率和匿名性。本文将探讨如何…

你还不知道如何利用AI提升学习效率吗?

前言 随着新学期的到来&#xff0c;校园里又恢复了往日的热闹。书声琅琅&#xff0c;青春洋溢&#xff0c;大学生们怀揣着梦想与希望&#xff0c;踏入了新的学习阶段。然而&#xff0c;在这个信息爆炸的时代&#xff0c;传统的学习方式是否还能满足我们的需求呢&#xff1f;答…

在 sql server 数据库中,查询数据库的占用的空间大小和数据库中各表的占用大小

1、如果只是查询数据库的大小的话&#xff0c;直接使用以下语句即可&#xff1a; EXEC sp_spaceused2、为了保证查询结果的实时性&#xff0c;推荐使用下面这个语句来确保统计数据是最新的&#xff1a; EXEC sp_spaceused updateusage NTRUE;执行完毕后结果是两个表&#xf…

Android终端如何快速接入GB28181平台实现实时音视频回传

技术背景 GB28181是由中国国家标准委员会发布的基于IP网络的安防视频监控标准。Android平台GB28181设备对接模块&#xff0c;主要涉及到视频监控领域&#xff0c;可实现不具备国标音视频能力的 Android终端&#xff0c;通过平台注册接入到现有的GB/T28181—2016服务&#xff0…

Ubuntu 下载/安装

官网 Enterprise Open Source and Linux | UbuntuUbuntu is the modern, open source operating system on Linux for the enterprise server, desktop, cloud, and IoT.https://ubuntu.com/ 下载 安装

代码签名证书有什么作用?

代码签名证书在软件开发和分发过程中具有多重重要作用&#xff0c;主要包括以下几个方面&#xff1a; 验证身份和来源&#xff1a;代码签名证书通过数字签名技术&#xff0c;验证软件发布者的身份&#xff0c;确保软件确实来自其声称的开发者或组织。这有助于用户识别并信任软件…

小试牛刀,开发你的第一个Java程序 -- HelloWorld

&#x1f680; 个人简介&#xff1a;某大型国企资深软件开发工程师&#xff0c;信息系统项目管理师、CSDN优质创作者、阿里云专家博主&#xff0c;华为云云享专家&#xff0c;分享前端后端相关技术与工作常见问题~ &#x1f49f; 作 者&#xff1a;码喽的自我修养&#x1f9…

C语言09--进程的内存镜像

C进程内存布局 任何一个程序&#xff0c;正常运行都需要内存资源&#xff0c;用来存放诸如变量、常量、函数代码等等。这些不同的内容&#xff0c;所存储的内存区域是不同的&#xff0c;且不同的区域有不同的特性。因此我们需要研究C语言的内存布局&#xff0c;逐个了解不同内存…

SQLynx如何提高企业数据库安全?

企业数据库的安全性直接关系到企业的运营稳定、客户隐私保护以及市场竞争力。SQLynx凭借技术优势和全面的防护策略&#xff0c;致力于为企业数据库安全提供了强有力的保障。 1. 多数据源支持 SQLynx企业版支持多种主流数据源&#xff0c;包括Oracle、PostgreSQL、MySQL、Mari…

无痕去除视频logo,视频去水印

视频素材带有logo&#xff0c;是我们在剪辑中经常会遇到的问题。那么&#xff0c;怎么快速去掉视频中的logo呢&#xff1f; 随着视频内容的不断丰富和多样化&#xff0c;很多人都开始学习视频剪辑技巧&#xff0c;其中一个重要的问题就是如何去掉视频中的logo。 我们一般在网上…

十一 面向对象技术(考点篇)试题

A &#xff1b;D&#xff0c;D。实际答案&#xff1a;C&#xff1b;D&#xff0c;D 考的很偏了。UML 2.0基础结构的设计目标是定义一个元语言的核心 UML 2.0 【InfrastructureLibrary】,通过对此核心的复用&#xff0c;除了可以定义一个自展的UML元模型&#xff0c;也可以 Infr…

OpenGauss 高性能高安全高可靠的企业级开源关系型数据库

openGauss | openGauss openGauss: 一款高性能、高安全、高可靠的企业级开源关系型数据库。 技术背景 openGauss内核深度融合华为在数据库领域多年的经验,结合企业级场景需求,持续构建竞争力特性。 自 2020 年 6 月开源以来,openGauss 一直围绕高性能、高可用、高智能、…

企业展厅设计关键转折点何在?如何确保展厅顺利实施?

随着科技的进步和市场竞争的加剧&#xff0c;各企业越来越注重自身的形象宣传和品牌推广。近期&#xff0c;数字多媒体技术在内容展览中所引起的广泛关注和讨论&#xff0c;让不少企业意识到&#xff0c;建设一个集创新、互动、科技于一体的企业多媒体展厅&#xff0c;是当下吸…