Grade 11 · TreesCitește în română

Parent array: root, leaves, levels, height

Original: Vectorul de tați: rădăcină, frunze, niveluri, înălțime

O(n²)C++1775 lines1 example

The idea

A rooted tree can be stored as a parent array: t[i] is the parent of node i, and for the root t[i] = 0. The root is the node with t = 0. The leaves are the nodes that are nobody's parent (they have no children). The level of a node is the number of edges on the path from the root to it (the root is on level 0); we find it by climbing from parent to parent up to the root. The height of the tree is the maximum level.

Original description (Romanian)

Un arbore cu rădăcină se poate memora prin vectorul de tați: t[i] este tatăl nodului i, iar pentru rădăcină t[i] = 0. Rădăcina este nodul cu t = 0. Frunzele sunt nodurile care nu apar ca tată al nimănui (nu au fii). Nivelul unui nod este numărul de muchii de pe drumul de la rădăcină la el (rădăcina este pe nivelul 0); îl aflăm urcând din tată în tată până la rădăcină. Înălțimea arborelui este nivelul maxim.

Complexity
O(n · h), where h is the height of the tree
Grade
Grade 11 (Clasa a XI-a)
Chapter
Trees

Examples

Example 1

Input

8
3 3 0 1 1 2 4 2

Expected output

Radacina: 3
Frunze: 5 6 7 8
Niveluri: 1 1 0 2 2 2 3 2
Inaltime: 3

The code

Comments are in Romanian, as in the original collection. Edit freely: you can reset at any time.

vectorul-de-tati.cpp
/*
 * Titlu: Vectorul de tați: rădăcină, frunze, niveluri, înălțime
 * Clasa: 11
 * Capitol: Arbori
 * Descriere: Un arbore cu rădăcină se poate memora prin vectorul de tați: t[i] este tatăl
 *            nodului i, iar pentru rădăcină t[i] = 0. Rădăcina este nodul cu t = 0. Frunzele
 *            sunt nodurile care nu apar ca tată al nimănui (nu au fii). Nivelul unui nod este
 *            numărul de muchii de pe drumul de la rădăcină la el (rădăcina este pe nivelul 0);
 *            îl aflăm urcând din tată în tată până la rădăcină. Înălțimea arborelui este
 *            nivelul maxim.
 * Complexitate: O(n · h), unde h este înălțimea arborelui
 *
 * Exemplu
 * Intrare:
 * 8
 * 3 3 0 1 1 2 4 2
 * Ieșire:
 * Radacina: 3
 * Frunze: 5 6 7 8
 * Niveluri: 1 1 0 2 2 2 3 2
 * Inaltime: 3
 */
#include <iostream>
using namespace std;

int t[100005], nrFii[100005];

int main()
{
    int n, radacina = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> t[i];
        if (t[i] == 0)
        {
            radacina = i;
        }
        else
        {
            nrFii[t[i]]++;
        }
    }

    cout << "Radacina: " << radacina << '\n';
    cout << "Frunze:";
    for (int i = 1; i <= n; i++)
    {
        if (nrFii[i] == 0)
        {
            cout << ' ' << i;
        }
    }
    cout << '\n';

    int inaltime = 0;
    cout << "Niveluri:";
    for (int i = 1; i <= n; i++)
    {
        int nivel = 0;
        for (int x = i; t[x] != 0; x = t[x])
        {
            nivel++;
        }
        cout << ' ' << nivel;
        if (nivel > inaltime)
        {
            inaltime = nivel;
        }
    }
    cout << '\n';
    cout << "Inaltime: " << inaltime << '\n';
    return 0;
}

Runs on a real g++ (C++17, -O2) through Compiler Explorer. Keep runs short; there's a time limit.