参考的分析:
蓝桥杯 试题 历届真题 左儿子右兄弟_okok__TXF的博客-CSDN博客
这道题的意思就是说,对于一个根,选一个子节点当左子树,其余的兄弟节点都变成他的右子树,不过顺序可以随便排列,给出一棵树,让我们求出这样转化后的最大树高。
具体分析可以参考上边的链接,他的思想就是说:
对于一个根的子节点,这些子节点当中子节点最多的优先级越高,越应该放在最底下,因为这样能保证后面更深。
这里定义两个结构:
设f[u]表示以u为根节点的最大树高。
f[u]表示最大树高:f[u]=子节点数目+最后一个兄弟作为根的最大深度
g[u]表示一个父节点是u的子节点序列
我们进行dfs深搜,每次选出最优子节点,什么是最优子节点?拥有子节点最多的一个子节点,选出来这个j后,我们就默认把他放在当前该子节点的根节点的左子节点的最右下方进行重构,求取当前最大深度:g[u].size()+f[j]
#include <bits/stdc++.h>
using namespace std;
const int N=100010;
int n;
//f[i]表示对应子节点数量+子树转化为二叉树后的最大高度
int f[N];
//g[i]记录父节点为i的子节点序列
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;
}