赞
踩
问题描述
对于一棵多叉树,我们可以通过 “左孩子右兄弟” 表示法,将其转化成一棵二叉树。
如果我们认为每个结点的子结点是无序的,那么得到的二叉树可能不唯一。
换句话说,每个结点可以选任意子结点作为左孩子,并按任意顺序连接右兄弟。
给定一棵包含 N N N 个结点的多叉树,结点从 1 1 1 至 N N N 编号,其中 1 1 1 号结点是根,每个结点的父结点的编号比自己的编号小。
请你计算其通过 “左孩子右兄弟” 表示法转化成的二叉树,高度最高是多少。注:只有根结点这一个结点的树高度为 0 0 0 。
例如如下的多叉树:
可能有以下
3
3
3 种 (这里只列出
3
3
3 种,并不是全部) 不同的 “左孩子右兄弟” 表示:
其中最后一种高度最高,为
4
4
4。
输入格式
输入的第一行包含一个整数
N
N
N。
以下
N
−
1
N −1
N−1 行,每行包含一个整数,依次表示
2
2
2 至
N
N
N 号结点的父结点编号。
输出格式
输出一个整数表示答案。
样例输入
5
1
1
1
2
样例输出
4
数据范围
对于 30% 的评测用例,
1
≤
N
≤
20
1 ≤ N ≤ 20
1≤N≤20;
对于所有评测用例,
1
≤
N
≤
100000
1 ≤ N ≤ 100000
1≤N≤100000。
题解
树形DP:
f[u]
:以点 u
为根节点,通过 “左孩子右兄弟” 表示法转化成二叉树后的最大高度;
f[u] = 子节点数量 + 子树转化为二叉树后的最大高度
;#include <bits/stdc++.h> using namespace std; const int N = 100010; int n; int f[N]; vector<int> g[N]; void dfs(int u) { f[u] = g[u].size(); int maxv = 0; for (int i = 0; i < g[u].size(); i ++) { int j = g[u][i]; dfs(j); maxv = max(maxv, f[j]); } f[u] += maxv; } int main() { cin >> n; for (int i = 2; i <= n; i ++) { int u; cin >> u; g[u].push_back(i); } dfs(1); cout << f[1] << endl; return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。