[蓝桥杯 2021 省 A] 左孩子右兄弟

一、问题描述

P8744 [蓝桥杯 2021 省 A] 左孩子右兄弟

二、问题简析

2.1 左孩子右兄弟

首先,我们要了解怎么通过“左孩子右兄弟”表示法将多叉树转化为二叉树:对于一棵多叉树,一个父节点有多个子节点,将第一个子节点作为父节点的左孩子,并与父节点相连;将剩余的子节点作为左孩子的右兄弟,并用边与左孩子相连(不是父节点);处理完所有子节点后,再按一样的规则处理其余父节点。

以该多叉树为例:
图1
处理子节点:
图2
1 为根节点“拉一下”二叉树:
图3
注意: 多叉树中根节点的子节点并不一定按图所示的顺序排列,更准确地说,是无序的,也就是说左孩子和右兄弟的选择是任意的

2.2 树状dp

d p i = dp_i= dpi= i i i 为根节点的二叉树的高度 A i . s i z e = A_i.size= Ai.size= 原多叉树中根节点 i i i 的子节点个数 j ∈ A i j \in A_i jAi根节点 i i i 的所有子节点
假设在原多叉树中,根节点 i i i 的子节点都是叶节点,即子节点没有子节点。结合上图,就是没有节点 6。显然,用“左孩子右兄弟”转化后, d p i dp_i dpi 仅取决于 i i i 的子节点的个数,即 d p i = A i . s i z e dp_i=A_i.size dpi=Ai.size
在上文的基础上,假设子节点不再是叶节点,即子节点有子节点。结合上图,就是考虑节点 6。从贪心的角度,为了使二叉树最高,肯定要尽可能“延长”树,即最高的子树放在最下面。本例中,就是把节点 2 放在最下面,因为以 2 为根节点的子树高度为 1 1 1,其余子树都为 0 0 0。贪心地处理后,最大高度就是根节点 i i i 的子节点个数 + 子树的最大高度

总结一下,

d p i = A i . s i z e + m a x ( d p j   ∣   j ∈ A i ) dp_i=A_i.size + max({dp_j~|~j\in A_i}) dpi=Ai.size+max(dpj  jAi)


三、AC代码

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int quickin(void)
{
	int ret = 0;
	bool flag = false;
	char ch = getchar();
	while (ch < '0' || ch > '9')
	{
		if (ch == '-')    flag = true;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9' && ch != EOF)
	{
		ret = ret * 10 + ch - '0';
		ch = getchar();
	}
	if (flag)    ret = -ret;
	return ret;
}

const int MAX = 1e5 + 3;
int N, dp[MAX];
vector<int> A[MAX];

void dfs(int x)
{
	vector<int> B = A[x];
	for (int i = 0; i < B.size(); i++)
	{
		dfs(B[i]);
		dp[x] = max(dp[x], dp[B[i]]);
	}
	dp[x] += B.size();
}

int main()
{
	#ifdef LOCAL
	freopen("test.in", "r", stdin);
	#endif
	
	N = quickin();
	for (int i = 2; i <= N; i++)
	{
		int a = quickin();
		A[a].push_back(i);
	}
	
	dfs(1);
	cout << dp[1] << endl;
	
	return 0;
}

  • 23
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值