Language: C++

#include <cst
#include <cassert>
#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
#include <list>
 
enum TNodeType {ntRoot, ntInternal, ntLeaf};
template<typename T>
class TTree;
 
template<typename T>
class TNode
{
    const T FValue;
    TTree<T>* FTree;
    TNode* FParent;
    TNode* FFirstChild;
    TNode* FLastChild;
    TNode* FNextSibling;
 
public:
    TNode(TTree<T>* Tree, const T& Value)
     : FValue(Value), FTree(Tree)
    {
        FParent      = NULL;
        FFirstChild  = NULL;
        FLastChild   = NULL;
        FNextSibling = NULL;
    }
    T Value()const
    {
        return FValue;
    }
    void Add(const T& Value)
    {
        TNode* Node = FTree->Erase(Value);
        if(Node == NULL) Node = new TNode(FTree, Value);
        Node->FParent = this;
        if(FFirstChild == NULL){
            FFirstChild = Node;
            FLastChild  = Node;
            return;
        }
        FLastChild->FNextSibling = Node;
        FLastChild = Node;
    }
    const TNode* Parent()const
    {
        return FParent;
    }
    const TNode* FirstChild()const
    {
        return FFirstChild;
    }
    const TNode* NextSibling()const
    {
        return FNextSibling;
    }
    const TNode* Find(const T& Value)const
    {
        // std::cout << "Find(" << Value << ")" << std::endl;
        if(FValue == Value) return this;
        for(const TNode* Child = FFirstChild; Child; Child = Child->FNextSibling){
            const TNode* Node = Child->Find(Value);
            if(Node) return Node;
        }
        return NULL;
    }
    TNode* Find(const T& Value)
    {
        return const_cast<TNode*>(const_cast<const TNode*>(this)->Find(Value));
    }
};
template<typename T>
class TTree
{
    typedef std::list<TNode<T>*> TList;
    TList FBuffer;
 
public:
    TTree()
    {}
    const TNode<T>* Find(const T& Value)const
    {
        for(typename TList::const_iterator It = FBuffer.begin(); It != FBuffer.end(); ++It){
            const TNode<T>* Node = (*It)->Find(Value);
            if(Node) return Node;
        }
        return NULL;
    }
    TNode<T>* Find(const T& Value)
    {
        return const_cast<TNode<T>*>(const_cast<const TTree*>(this)->Find(Value));
    }
    TNode<T>* Erase(const T& Value)
    {
        for(typename TList::iterator It = FBuffer.begin(); It != FBuffer.end(); ++It){
            if((*It)->Value() == Value){
                TNode<T>* Node = *It;
                FBuffer.erase(It);
                return Node;
            }
        }
        return NULL;
    }
    TNode<T>* operator [](const T& Value)
    {
        TNode<T>* Node = Find(Value);
        if(Node) return Node;
        Node = new TNode<T>(this, Value);
        FBuffer.push_back(Node);
        return Node;
    }
};
 
template<typename T>
int GetNodeDepth(const TNode<T>* Node)
{
    assert(Node);
    int Depth = 0;
    while(Node->Parent()){
        Node = Node->Parent();
        Depth++;
    }
    return Depth;
}
 
template<typename T>
TNodeType GetNodeType(const TNode<T>* Node)
{
    assert(Node);
    if(Node->Parent() == NULL) return ntRoot;
    if(Node->FirstChild())     return ntInternal;
    return ntLeaf;
}
std::string GetNodeTypeText(const TNodeType& Type)
{
    switch(Type){
    case ntRoot:     return "root";
    case ntInternal: return "internal node";
    case ntLeaf:     return "leaf";
    }
    assert(false);
    return "";
}
 
template<typename T>
std::string GetChildrenText(const TNode<T>* Node)
{
    assert(Node);
    std::stringstream ss;
    ss << "[";
    const TNode<T>* Child = Node->FirstChild();
    while(Child){
        ss << Child->Value();
        Child = Child->NextSibling();
        if(Child) ss << ", ";
    }
    ss << "]";
    return ss.str();
}
template<typename T>
void PrintNode(const TNode<T>* Node)
{
    assert(Node);
// node 1: parent = 0, depth = 1, internal node, [2, 3]    
    // std::cout << 
    // "node "       << Node->Value() <<
    // ": parent = " << (Node->Parent() ? Node->Parent()->Value() : -1) <<
    // ", depth = "  << GetNodeDepth(Node) <<
    // ", "          << GetNodeTypeText(GetNodeType(Node)) <<
    // ", "          << GetChildrenText(Node) <<
    // std::endl;
    std::printf("node %d: parent = %d , depth = %d, %s, %s\n",
        Node->Value(),
        (Node->Parent() ? Node->Parent()->Value() : -1),
        GetNodeDepth(Node),
        GetNodeTypeText(GetNodeType(Node)).c_str(),
        GetChildrenText(Node).c_str()
    );
}
template<typename T>
void AddChildren(TNode<T>* Node, int k, std::istream& is)
{
    assert(Node);
    for(int i = 0; i < k; ++i){
        int c;
        // std::cin >> c;
        // is >> c;
        std::scanf("%d", &c);
        // std::cout << "i:" << i << " c:" << c << std::endl;
        Node->Add(c);
    }
}
int main()
{
    // std::cin.tie(0);
    // std::ios::sync_with_stdio(false);
    int n;
    // std::cin >> n;
    std::scanf("%d", &n);
    std::vector<int> List(n);
    TTree<int> Tree;
    for(int i = 0; i < n; ++i){
        // std::string str;
        // std::getline(std::cin, str);
        // std::stringstream ss(str);
        int id;
        int k;
        // std::cin >> id >> k;
        // ss >> id >> k;
        std::scanf("%d %d", &id, &k);
        List[i] = id;
        // std::cout << "id:" << id << " k:" << k << " i:" << i << " n:" << n << std::endl;
        if(i && k == 0) continue;
        AddChildren(Tree[id], k, std::cin);
    }
    std::sort(List.begin(), List.end());
    for(std::size_t i = 0; i < List.size(); ++i){
        const TNode<int>* Node = Tree.Find(List[i]);
        PrintNode(Node);
    }
    return 0;
}

Compiler output:
a.cc:1:14: error: missing terminating > character
    1 | #include <cst
      |              ^
a.cc:1:10: fatal error: cst: No such file or directory
    1 | #include <cst
      |          ^
compilation terminated.