原题链接:P8744 [蓝桥杯 2021 省 A] 左孩子右兄弟 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
原题目:
分析:这是一道贪心+dfs题目,首先我们思考只有两层的情况,对于每个子节点,剩余子节点都为兄弟节点,发现树的高度就是父节点的子节点数量。现在我们假设有三层,再将第二层的节点视为父节点,发现它们的高度依然是它们所拥有的子节点数量,因此我们选择拥有子节点数量最多的节点为最后选择的节点,让它的兄弟节点左向排列作为它的垫脚石,由于我们每次贪心地选择拥有子节点数最多的节点,因此他的兄弟节点所形成的高度必定小于主路径(如下图)。
这里给出AC代码:
n = int(input())
fa = [-1,-1] # 添加不存在的编号0节点,不存在父节点,1节点不存在父节点
g = [[] for _ in range(n+1)]
for i in range(n - 1):
fa.append(int(input()))
for j in range(2, n+1): # 节点索引从2开始输入
g[fa[j]].append(j) # g[x]储存的是节点x拥有的子节点
def dfs(x):#需要传递的是以该节点作为根节点的最高树高
max_y = 0
len_x = len(g[x]) # 初始化为这个节点所拥有的孩子数量
if g[x] == []:#如果不存在子节点,则这个节点的高度为0
return 0
else:
for y in g[x]:
len_y = dfs(y)
max_y = max(max_y, len_y)#贪心选择拥有子节点最多的节点
return len_x + max_y
print(dfs(1)) # 传入根节点索引1
推荐灵神的课呜呜呜,本采集第一次写这种题这么顺畅,感恩灵神,
指路:树形 DP:树的直径【基础算法精讲 23】_哔哩哔哩_bilibili