题意:要求我们在树上面选择两个点,要求这两个节点不相邻,也就是说不能同时选择a,b节点:
然后要求这两个节点的值的和最大。
假设我们选了n个节点,现在我们要枚举这n个节点,从这n个节点里面选节点,达到价值最大。
假设我们选了i节点,dp[i]就表示选择i节点价值最大。
那么既然可以选择i节点,那我也可以选择[1,i-1]节点。我们用dp[j]表示i-1这个节点的价值
dp[j]+a[i]就把最大价值的两个节点加起来了。
最后我们再按树深遍历所有节点。
伪代码思想
假设输入的树的结构如下:
1
/ \
2 3
/ \ \
4 5 6
根据这个树的结构,我们可以进行DFS遍历,并计算每个节点的深度。假设我们得到的深度为:
1: 1
2: 2
3: 2
4: 3
5: 3
6: 3
接下来我们对代码进行分析:
- 首先,我们通过DFS遍历树,计算每个节点的深度,并将深度相同的节点放在了一起。这样做的目的是为了后续的动态规划计算做准备。
- 在主函数中,我们输入了树的节点个数n,并且输入了每个节点的父节点p[i]和节点的价值a[i]。然后调用dfs(1, 0)进行深度优先搜索。
- 在DFS遍历后,我们进入动态规划的计算。我们从树的最底层开始,对每个节点进行遍历。对于每个节点u,我们先将其价值初始化为a[u],然后从下一层开始,对于每个节点v,如果v不是u的相邻节点(即p[v]不等于u),则我们比较dp[u]和dp[v]+a[u]的大小,取较大值更新dp[u]。最后,我们将mx更新为dp[u]和mx中的较大值。
- 最后输出mx,即为整棵树的最大价值和。
code