- 收集树上所有苹果的最少时间
给你一棵有 n 个节点的无向树,节点编号为 0 到 n-1 ,它们中有一些节点有苹果。通过树上的一条边,需要花费 1 秒钟。你从 节点 0 出发,请你返回最少需要多少秒,可以收集到所有苹果,并回到节点 0 。
无向树的边由 edges 给出,其中 edges[i] = [fromi, toi] ,表示有一条边连接 from 和 toi 。除此以外,还有一个布尔数组 hasApple ,其中 hasApple[i] = true 代表节点 i 有一个苹果,否则,节点 i 没有苹果。
示例 1:
输入:n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], hasApple = [false,false,true,false,true,true,false]
输出:8
解释:上图展示了给定的树,其中红色节点表示有苹果。一个能收集到所有苹果的最优方案由绿色箭头表示。
示例 2:
输入:n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], hasApple = [false,false,true,false,false,true,false]
输出:6
解释:上图展示了给定的树,其中红色节点表示有苹果。一个能收集到所有苹果的最优方案由绿色箭头表示。
示例 3:
输入:n = 7, edges = [[0,1],[0,2],[1,4],[1,5],[2,3],[2,6]], hasApple = [false,false,false,false,false,false,false]
输出:0
提示:
1 <= n <= 10^5
edges.length == n-1
edges[i].length == 2
0 <= fromi, toi <= n-1
fromi < toi
hasApple.length == n
思路:递归
不访问不必要的结点,必要的结点最多访问1次
访问某一个节点:
1、该节点有苹果
2、该节点的子节点有苹果
数据结构:建立二维矩阵保存该树形结构
dfs(cur):定义为当前结点下面访问所有品过需要的步骤
那么dfs(cur) = sum( ( dfs(child) +2) if case1/2 else 0 for child in childs )
若子节点有苹果或者子节点的字数有苹果,那个这个子节点必须访问:
意思就是地柜的定义:当前节点的代价 = 所有子节点代价 + 2(来回)
懂了,传参进来是一个二维的边 和 苹果数组 还有n个结点
graph = [[] for _ in range(n)]for e in edges:graph[e[0]].append(e[1])graph[e[1]].append(e[0])seen = [0 for _ in range(n)]def dfs(cur: int): # 定义为当前结点遍历完所需要的总共时间步骤seen[cur] = 1cur_cost = 0for child in graph[cur]:if seen[child] == 1:continuecost = dfs(child) # 判断当前这个节点中自接待呢有没有苹果if cost > 0 or hasApple[child]: # 如果当前子节点有苹果或者子节点的子节点有苹果cur_cost = cost + 2return cur_costreturn dfs(0)