from functools import cache
from typing import List
class Solution:
# edges[i] = [ui, vi, wi] 表示一条从节点 ui 到 vi 的有向边,边的权值为 wi
def maxWeight(self, n: int, edges: List[List[int]], k: int, t: int) -> int:
# 初始化一个邻接表 g,用于表示有向图。
# g 是一个长度为 n 的列表,每个元素是一个空列表,表示该节点的出边
g = [[] for _ in range(n)]
# 遍历 edges 中的每一条边,将元组(y, wt) 添加到 g[x] 中,表示从 x 出发的一条有向边
for x,y,wt in edges:
g[x].append((y, wt))
# 初始化最大边权和为-1
ans = -1
# 这是一个装饰器,用于缓存 dfs 函数的结果,避免重复计算(也可以用 vis 哈希集合来记录访问状态)
# 这里的 dfs 函数没有显式返回值,但 @cache 仍然会记录函数的调用状态
# cache 的键是 dfs 函数的参数组合 (x, i, s),由于 dfs 函数没有显式返回值(返回 None),cache 存储的值是 None
# 但 cache 的主要作用是记录“是否已经计算过某个状态”,而不是存储具体的计算结果
# 如果在递归过程中多次遇到相同的 (x, i, s),@cache 会直接跳过重复计算,直接返回 None
@cache
# 深度优先搜索(DFS)
# x: 当前节点。
# i: 当前已经走过的边数。
# s: 当前路径的总权重。
def dfs(x:int, i:int, s:int) ->None:
# 如果 i == k,表示已经走过 k 条边,更新 ans 为 max(ans, s)
if i == k:
nonlocal ans
ans = max(ans, s)
return
for y, wt in g[x]:
# 如果 s + wt < t,则递归调用 dfs(y, i + 1, s + wt)
if s + wt < t:
dfs(y,i+1, s+wt)
for x in range(n):
# 可以以任意节点为起点
dfs(x, 0, 0)
return ans
a = Solution()
print(a.maxWeight(n = 3, edges = [[0,1,1],[1,2,2]], k = 2, t = 4))
将cache替换成哈希集合
from typing import List
class Solution:
def maxWeight(self, n: int, edges: List[List[int]], k: int, t: int) -> int:
g = [[] for _ in range(n)]
for x, y, wt in edges:
g[x].append((y, wt))
ans = -1
vis = set() # 用 vis 哈希集合替代 @cache
def dfs(x: int, i: int, s: int) -> None:
nonlocal ans
if (x, i, s) in vis: # 如果状态已访问过,直接返回
return
vis.add((x, i, s)) # 标记当前状态为已访问
if i == k:
ans = max(ans, s)
return
for y, wt in g[x]:
if s + wt < t:
dfs(y, i + 1, s + wt)
for x in range(n):
dfs(x, 0, 0)
return ans
a = Solution()
print(a.maxWeight(n=3, edges=[[0,1,1],[1,2,2]], k=2, t=4)) # 输出: 3