LQ0135 左孩子右兄弟DFS+二叉树

Posted 海岛Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LQ0135 左孩子右兄弟DFS+二叉树相关的知识,希望对你有一定的参考价值。

题目来源:蓝桥杯2021初赛 C++ A组H题

题目描述
对于一棵多叉树,我们可以通过“左孩子右兄弟” 表示法,将其转化成一棵二叉树。
如果我们认为每个结点的子结点是无序的,那么得到的二叉树可能不唯一。
换句话说,每个结点可以选任意子结点作为左孩子,并按任意顺序连接右兄弟。
给定一棵包含N 个结点的多叉树,结点从1 至N 编号,其中1 号结点是根,每个结点的父结点的编号比自己的编号小。
请你计算其通过“左孩子右兄弟” 表示法转化成的二叉树,高度最高是多少。
注:只有根结点这一个结点的树高度为0 。
例如如下的多叉树:

可能有以下3 种(这里只列出3 种,并不是全部) 不同的“左孩子右兄弟”表示:

其中最后一种高度最高,为4。

输入格式
输入的第一行包含一个整数N。
以下N-1 行,每行包含一个整数,依次表示2 至N 号结点的父结点编号。
对于30% 的评测用例,1 ≤ N ≤ 20;
对于所有评测用例,1 ≤ N ≤ 100000。

输出格式
输出一个整数表示答案。

输入样例
5
1
1
1
2

输出样例
4

问题分析
选任意顺序将所有子节点中任选作为左结点,将该结点的兄弟结点依次在右侧连接,最后形成一个二叉树,使得二叉树高度最高。
以1为根结点。用vector来存储图。用DFS来计算高度。
还有一种解法是,用DP来实现。

AC的C++语言程序如下:

/* LQ0135 左孩子右兄弟 */

#include <iostream>
#include <vector>

using namespace std;

const int N = 100000 + 1;
vector<int> g[N];

int dfs(int k)

    if (g[k].size()) 
        int maxh = 0;
        for (int i = 0; i < g[k].size(); i++)
          maxh = max(maxh, dfs(g[k][i]));
        return maxh + g[k].size();
     else
        return 0;


int main()

    int n, u;
    cin >> n;
    for (int v = 2; v <= n; v++) 
        cin >> u;
        g[u].push_back(v);
    
    
    cout << dfs(1) << endl;
    
    return 0;

以上是关于LQ0135 左孩子右兄弟DFS+二叉树的主要内容,如果未能解决你的问题,请参考以下文章

第十二届蓝桥杯 ——左孩子右兄弟

多叉树转换二叉树

将一棵树转换为二叉树后,为什么根节点没有右子树

数据结构(十四)——二叉树

[数据结构]树森林与二叉树之间的相互转换方法

[数据结构]树森林与二叉树之间的相互转换方法