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

写代码的第四十三天
开始图了
啊啊啊啊好慌啊

98. 所有可达路径

思路

本题使用深度优先搜索的情况,所以就是在一条路走到黑,没有结点了,就回溯回到上一个结点,继续搜索。本题在我看来的难度太多了,初始化我就不会写,输出我也不会写,我就会回溯那一点。
解决问题1:初始化输入怎么写?n, m = map(int, input().split())解释一下这行代码,input() 函数用于接收用户的输入。input().split() 将用户输入的内容按空格分割成一个字符串列表。map(int, input().split()) 利用 map() 函数将列表中的每个元素转换为整数类型。所以整行代码的作用是将用户输入的一行空格分隔的数字转换为整数类型并存储在一个迭代器或列表中,可以用于进一步的处理。
解决问题2:如何根据输入构建图?图的题都是给出几行数字,第一行是结点个数和边的个数,下面是根据边的个数给出每条边相邻的结点。构建图的方法有两种,一种是邻接矩阵的方法,一种是邻接表的方法。首先用邻接矩阵的方式:根据给出的结点个数n进行构建邻接矩阵,构建出(n+1)(n+1)维度的矩阵并初始化为0,当结点i和j之间存在边,那么将矩阵中的数值存储为1,所以当前的邻接矩阵就可以代表图结构了。邻接表法:python中常用字典(dictionary)来表示。每个节点的邻居节点可以用一个列表来表示。graph = defaultdict(list) 用这句代码创建了一个名为 graph 的默认字典,其中的值默认为一个空列表,当访问一个不存在的键(即一个节点)时,会自动创建一个空列表作为该节点的邻居节点列表,无需手动初始化。
解决问题3:回溯过程?根据回溯三部曲。邻接矩阵:第一步参数和返回值,本题将过程中的路径path作为参数,将最后的输出结果result也作为参数,也可以作为全局变量设置;第二步终止条件,本题要求是从结点1到n的路径,那么当结点遍历到n的时候其中的一条路径就结束了,将这个路径path.copy()加入结果result中;第三步回溯过程,本题的矩阵是(n+1)
(n+1),所以矩阵下标从1到n+1才是我们要用的结点,需要注意的是不是每个结点都要,而是在构成图的矩阵中,值为1的点才进行回溯!!!!所以回溯中for循环遍历从1开始到n+1结束,回溯过程是先把当前结点append进path中,然后dfs递归,然后将该结点pop出去进行回溯。path初始为1的意思是最开始一定是从第一个结点走出来的。邻接表:第一步和第二步与上面一样,第三步中,需要对for循环做改进,for循环用来回溯,找上一个结点,所以直接看在当前点在不在graph[x]这个列表中。
解决问题4:输出结果怎么写?根据输出要求,最后不能有空格,所以按照这个形式输出print(’ '.join(map(str, path)))。
正确代码(邻接矩阵)

def dfs(graph, x, n, path, result):
    if x == n:
        result.append(path.copy())
        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 for _ in range(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
def dfs(graph, x, n, path, result):
    if x == n:
        result.append(path.copy())
        return
    for 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 path in result:
            print(' '.join(map(str, path)))
if __name__ == "__main__":
    main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值