代码随想录算法训练营第五十天 | 图论理论、深搜理论 98.所有可达路径 广搜理论

理论基础:

图论理论基础

文章链接

深搜理论基础

文章链接

广搜理论基础

文章链接


98.所有可达路径:

题目链接:98.所有可达路径
本题是给出 n 个节点的图,节点编号从1到n,找出所有1 到 n 的路径。
ACM模式,因此需要存储图

图的存储

邻接矩阵
n, m = map(str, input().split())	# n是节点个数,m是边数
# 为了让节点编号从1开始,因此邻接矩阵大小为(n + 1) * (n + 1)
graph = [[0] * (n + 1) for _ in range(n + 1)]
for _ in range(m):
	s, t = map(str, input().split())
	graph[s][t] = 1
邻接表

以字典形式保存邻接表:key(节点):[连接节点]

from collections import defaultdict
n, m = map(int, input().split())
graph = defaultdict(list)	# 值为列表
for _ in range(m):
	s, t = map(str, input().split())
	graph[s].append(t)

深度优先搜索求全部路径

因为是求全部路径,所以也用到了回溯
递归三部曲

  • 参数和返回值
    参数:x为当前节点,n为目标节点,graph保存图,path保存当前路径,result保存全部路径,没有返回值。(PS:path和result可以定义成全局变量不放在参数中)
  • 边界条件:
    当前节点x为目标节点时,保存当前路径再返回
if x == n:
	result.append(path[:])	# 注意这里要保存的是复制品
	return 1
  • 正常递归
    遍历当前节点x连接的节点,将其加入path中后进行dfs,再回溯
# 邻接矩阵
for i in range(1, n):
	if graph[x][i] == 1:
		path.append(i)
		dfs(i, n, graph, path, result)
		path.pop() # 回溯

# 邻接表
for i in graph[x]:
	path.append(i)
	dfs(i, n, graph, path, result)
	path.pop()

需要注意的是,前面定义递归时path已经保存了当前节点,因此调用时path不应当为空列表
dfs(1, n, graph, [1], result) # 注意path
代码

"""
邻接表
"""
from collections import defaultdict

def dfs(x, n, graph, path, result):
    """
    x为当前遍历到的节点,n为目标节点
    graph为邻接表,path为当前遍历的路径,result存储所有路径
    """
    if x == n:
        result.append(path[:])  # 记得这里要存的是path的复件
        return 1
    for i in graph[x]:
        path.append(i)
        dfs(i, n,graph, 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(1, n, graph, [1], result)
    if result == []:
        print(-1)
    else:
        for path in result:	# 最后打印全部路径时,要求每个路径独占一行,路径中的节点之间有空格,最后一个节点后无空格
            print(' '.join(map(str, path)))
if __name__ == "__main__":
    main()
"""
邻接矩阵
"""
def dfs(x, n, matrix, path, result):
    """
    x为当前遍历到的节点,n为目标节点
    matrix为邻接矩阵,path为当前遍历的路径,result存储所有路径
    """
    if x == n:
        result.append(path[:])  # 记得这里要存的是path的复件
        return 1
    for i in range(1, n + 1):
        if matrix[x][i]:
            path.append(i)
            dfs(i, n, matrix, path, result)
            path.pop()  # 回溯
 
 
def main():
    n, m = map(int, input().split())
    # 邻接矩阵
    matrix = [[0] * (n + 1) for _ in range(n + 1)]
    for _ in range(m):
        s, t = map(int, input().split())
        matrix[s][t] = 1
     
    result = []
    dfs(1, n, matrix, [1], result)
    if result == []:
        print(-1)
    else:
        for path in result:
            print(' '.join(map(str, path)))
if __name__ == "__main__":
    main()


学习时间:

提示:这里可以添加计划学习的时间

例如:

  • 周一至周五晚上 7 点—晚上9点
  • 周六上午 9 点-上午 11 点
  • 周日下午 3 点-下午 6 点

学习产出:

提示:这里统计学习计划的总量

例如:

  • 技术笔记 2 遍
  • 优快云 技术博客 3 篇
  • 习的 vlog 视频 1 个
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值