记一道计算有向无环图的每个节点通过的路径个数的题目
菜鸡不会什么高级的方法,还希望有更好的方式解这道题。
题目
给定一张有向无环图,图中包含n个节点和m条有向边,每个节点都标有一个唯一的整数编号,从1~n,我们定义经过一个节点的路径是指包含该节点的路径,且该路径可以反包含零条边(即路径只包含节点本身)。
样例一:
5 4
1 2
1 3
2 4
3 5
输出:
5
4
4
3
3
样例 二:
3 3
1 2
1 2
2 3
输出:
5
6
4
分析解释
对于样例一
输出的解释
节点1有5条路径经过它:1, 1->2, 1->3, 1->2->4, 1->3->5。
节点2有4条路径经过它:2, 1->2, 1->2->4, 2->4。
节点3有4条路径经过它:3, 1->3, 1->3->5, 3->5。
节点4有3条路径经过它:4, 1->2->4, 2->4。
节点5有3条路径经过它:5, 1->3->5, 3->5。
样例二:
输出的解释:
(1指向2的两条路径认为是两个)
节点1有5条路径经过它:1, 1->2, 1->2, 1->2->3, 1->2->3。
节点2有6条路径经过它:2, 1->2, 1->2, 1->2->3, 1->2->3,2->3。
节点3有4条路径经过它:3, 2->3, 1->2->3, 1->2->3。
代码
# 定义函数count_paths,接受边的列表edges和节点总数n作为参数
def count_paths(edges, n):
# 初始化一个字典graph表示图,键为节点,值为与其相连的节点列表
graph = {i: [] for i in range(1, n + 1)}
# 初始化一个列表count记录每个节点的路径数量,初始为0
count = [0 for i in range(n + 1)]
# 初始化一个字符串列表strlist用于存储DFS过程中生成的路径字符串
strlist = []
# 初始化一个空字符串str2用于拼接路径
str2 = ''
# 根据输入的边列表构造图
for u, v in edges:
graph[u].append(v)
# 对于图中的每个节点执行深度优先搜索并统计路径
for node in range(1, n + 1):
dfs(graph, node, strlist, str2) # 执行DFS
tongji(node, strlist, count) # 统计路径数量
# 返回除第一个节点外的所有节点的路径数量(因为第一个节点默认为0,无需计算)
return count[1:]
# 定义深度优先搜索函数dfs,递归地遍历图
def dfs(graph, node, strlist, str2):
# 构造当前节点的路径字符串并添加到strlist中
str1 = str2 + str(node)
strlist.append(str1)
# 遍历与当前节点相连的所有节点,继续进行深度优先搜索
for i in graph[node]:
dfs(graph, i, strlist, str1)
# 定义统计函数tongji,计算以node为起点在strlist中出现的路径数量
def tongji(node, list, count):
for i in list:
# 如果节点存在于路径中,则增加该节点的路径计数
if str(node) in i:
count[node] += 1
# 主程序部分:读取输入,处理数据,调用count_paths函数并打印结果
n, m = list(map(int, input().split())) # 读取节点数n和边数m
edges = [] # 初始化边的列表
for i in range(m): # 根据边数m读取每一条边
list1 = list(map(int, input().split())) # 读取一条边的两个节点
edges.append(list1) # 将这条边添加到edges列表中
#print(edges) # (这行是调试用的,可删除或注释)
print(count_paths(edges, n)) # 调用count_paths函数并输出结果