蓝桥杯动态规划-左孩子右兄弟

题目描述

对于一棵多叉树,我们可以通过 “左孩子右兄弟” 表示法,将其转化成一棵二叉树。

如果我们认为每个结点的子结点是无序的,那么得到的二叉树可能不唯一。

换句话说,每个结点可以选任意子结点作为左孩子,并按任意顺序连接右兄弟。

给定一棵包含 NN​​ 个结点的多叉树,结点从 11​​ 至 NN​ 编号,其中 11 号结点是根,每个结点的父结点的编号比自己的编号小。

请你计算其通过 “左孩子右兄弟” 表示法转化成的二叉树,高度最高是多少。

注:只有根结点这一个结点的树高度为 00​。

输入描述

输入的第一行包含一个整数 NN​​​。 以下 N −1N−1​​ 行,每行包含一个整数,依次表示 22​ 至 NN 号结点的父结点编号。

输出描述

输出一个整数表示答案。

输入输出样例

示例 1

输入

5
1
1
1
2

输出

4

评测用例规模与约定

对于 30\%30%​​ 的评测用例,1 \leq N \leq 201≤N≤20​;

对于所有评测用例,1 \leq N \leq 1000001≤N≤100000。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M

 

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
import java.util.Vector;

public class Main {
	
	static Map<Integer, Vector<Integer>> map;
	static Vector<Integer> vector[];
	static int [] dp;

	public static void main(String[] args) {
		
		Scanner scanner = new Scanner(System.in);
	

		int N = scanner.nextInt();
		map = new HashMap<Integer, Vector<Integer>>();
		 vector = new Vector[N+10];
		 dp  = new int [N+10];
		 for(int i=1;i<=N;i++) {
			 vector[i] = new Vector<Integer>();
		 }
		 
		for(int i=2;i<=N;i++) {
			int a = scanner.nextInt();
			vector[a].add(i);
		}

		dfs1(1);
		System.out.print(dp[1]);
//		System.out.print(dfs(1,vector[1]));
	}

	private static void dfs1(int i) {
		int count = 0;
		for(int j:vector[i]) {
			dfs1(j);
			count = Math.max(dp[j], count);
		}
		dp[i] = vector[i].size()+count;
	}
	
	private static int dfs(int i,Vector<Integer> set) {

		if(set == null) {
			return 0;
		}
		int count = 0;
		Iterator<Integer> t = set.iterator();
		while(t.hasNext()) {
			int n = t.next();
			count = Math.max(dfs(n, vector[n]), count);
		}
		return count+set.size();

	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萤火的微亮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值