试题 历届真题 左孩子右兄弟
震惊:孩子居然是标题党的字。。。。CSDN不让标题有孩子。。
题目解释
资源限制
时间限制:1.0s 内存限制:256.0MB
题目可能乍看不是很懂。我先来把题目意思给说一下。(输入输出样例就不用我说了吧)
反正死死地按着左孩子有右兄弟的规则,尽可能地把这个树画长一点。
- 如果只有一个孩子,那好办,直接画在左边即可。
- 如果有多个孩子呢?
通过对样例发现,2 3 4作为1的孩子,画的先后顺序还是有一定讲究的。
通过我测试了几个,直接下结论,用左孩子右兄弟 画孩子结点,
按照 孩子结点的下面所有结点数从少到多的顺序画
??????????????什么意思
比如1,画它的孩子结点(2,3,4)中的一个
孩子结点的下面所有结点数(就是2,3,4的下面所有结点的结点数)
2 -> 1 3-> 0 4->0
所以,画孩子结点的优先级 4 == 3 > 2
例子:
例子1.
看这个例子,先画1:
画孩子结点,2,3,4 看谁下面的结点数少,就先画它,发现是 3, 然后是 2, 然后是4
如果下面节点数有一样的,那就先后无所谓了
最终结果
下面再给一个例子:
大家画画看看
结论:
发现结论,
以例子1的树为例子
-
第二层对高度的贡献值就是第二层的节点数;
-
找 2 3 4 谁下面的节点数多,那么下一层对高度的贡献值就是结点多的,我们发现是4,有三个节点,
对高度贡献值3,
这样 3 + 3 = 6
以让大家画的树为例子:
二的结点有5个,3(1的孩子数)+5 = 8
代码
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1e5+5;
vector<int> tree[N];
int n, father;
int findChils( int i )
{
int ans = 0;
for ( int k = 0; k < tree[i].size(); ++k ) {
int child = tree[i][k];
ans = max(ans, findChils(child));
}
return ans + tree[i].size();
}
int main()
{
cin >> n;
for ( int i = 2; i <= n; ++i ) {
cin >> father;
tree[father].push_back(i);
}
// for ( int i = 1; i <= n; ++i ) {
// cout << i << "-->" << findChils(i) << endl;
// }
cout << findChils(1) << endl;
return 0;
}