这是函数的定义部分,dfs 函数接受三个参数:
def dfs(x: int, fa: int, d: int) -> int
if d > k:
return 0
cnt = 1
for y in g[x]:
if y != fa:
cnt += dfs(y, x, d + 1)
return cnt
x(int类型):表示当前正在访问的节点的编号。fa(int类型):表示节点x的父节点的编号。这是为了在遍历过程中避免沿着已经访问过的路径返回,防止形成死循环。d(int类型):表示从根节点到当前节点x的深度(路径长度)。
一、树结构中避免访问父节点的原理
在树结构中,任意两个节点之间只有一条路径,每个节点(除了根节点)都有唯一的父节点。代码中的 fa 参数记录了当前节点 x 的父节点,通过 if y != fa 判断,可以确保不会从当前节点回到父节点,从而避免循环。
例如,在调用 dfs(x, fa, d) 时:
x是当前节点fa是x的父节点- 遍历
x的邻接节点y时,如果y等于fa,说明这个邻接节点是父节点,应该跳过
二、图结构中这种方法的局限性
在图结构中,节点之间可能存在多条路径和环路,仅仅记录父节点是不够的。例如:
- 如果图中存在环,即使跳过父节点,仍然可能通过其他路径回到已经访问过的节点
- 对于无向图中的边
(u, v),在遍历u的邻接节点时会访问v,而遍历v的邻接节点时又会访问u,导致重复遍历
三、图结构中的正确处理方法
在图中进行 DFS 时,通常需要使用一个全局的 visited 数组或集合来记录已经访问过的节点,避免重复访问。以下是修改后的代码示例:
visited = set() # 全局集合,记录已访问的节点
def dfs(x: int, d: int) -> int:
if d > k:
return 0
if x in visited: # 如果节点已被访问,直接返回0
return 0
visited.add(x) # 标记当前节点为已访问
cnt = 1
for y in g[x]:
cnt += dfs(y, d + 1) # 递归访问邻接节点,不再需要fa参数
return cnt
四、总结
- 树结构:由于其无环特性,使用
fa参数可以有效避免重复访问父节点 - 图结构:必须使用
visited集合来记录已访问节点,否则会导致:- 无限循环(如果图中存在环)
- 重复计算(即使图中没有环

被折叠的 条评论
为什么被折叠?



