题目 2606: 蓝桥杯2021年第十二届省赛真题-左孩子右兄弟
时间限制: 1Sec 内存限制: 128MB 提交: 866 解决: 287
题目描述
对于一棵多叉树,我们可以通过 “左孩子右兄弟” 表示法,将其转化成一棵
二叉树。
如果我们认为每个结点的子结点是无序的,那么得到的二叉树可能不唯一。换句话说,每个结点可以选任意子结点作为左孩子,并按任意顺序连接右兄弟。
给定一棵包含 N 个结点的多叉树,结点从 1 至 N 编号,其中 1 号结点是根,每个结点的父结点的编号比自己的编号小。请你计算其通过 “左孩子右兄弟” 表示法转化成的二叉树,高度最高是多少。注:只有根结点这一个结点的树高度为 0 。
例如如下的多叉树:
可能有以下 3 种 (这里只列出 3 种,并不是全部) 不同的 “左孩子右兄弟”
表示:
其中最后一种高度最高,为 4。
输入
输入的第一行包含一个整数 N。
以下 N 1 行,每行包含一个整数,依次表示 2 至 N 号结点的父结点编号。
输出
输出一个整数表示答案。
样例输入
5
1
1
1
2
样例输出
4
思路:
一个树的最高高度情况为所有子节点都依次排在左子树时(如下图最后一个树,4,3,2为1的孩子都排在左子树,而2是最高的左子树,排最下)而最高高度的子节点排在左子树的最下层。代码有详细注释。
技巧:
要把sys的setrecursionlimit设大一点不然在蓝桥杯官网会超过递归深度!(离谱的问题,建议比赛的时候都设大一点)
代码:
import sys
sys.setrecursionlimit(100000)
N = int(input())
# 下标结点,tree[i][0]为其父节点,其余为孩子结点
tree = [[-1] for _ in range(N+1)]
for i in range(2, N+1):
fa = int(input().strip())
tree[i][0] = fa
tree[fa].append(i)
def getHigh(node):
# 叶子结点
if len(tree[node]) == 1:
# dp[node] = 0
return 0
# 最高高度为其孩子结点数+最高的孩子树的高度
# 求最高孩子树高度
maxhigh = 0
for j in range(1, len(tree[node])):
maxhigh = max(maxhigh, getHigh(tree[node][j]))
return len(tree[node])-1+maxhigh
print(getHigh(1))