Problem p02280 (C++) — buggy submission, verdict: Runtime Error

#include <cmath>
#include <iomanip>
#include <iostream>
#include <math.h>
#include <string>
#include <vector>
using namespace std;

// A rooted binary tree is a tree with a root node in which every node has at
// most two children.

// Your task is to write a program which reads a rooted binary tree T
//  and prints the following information for each node u of T:

// node ID of u
// parent of u
// sibling of u
// the number of children of u
// depth of u
// height of u
// node type (root, internal node or leaf)
// If two nodes have the same parent, they are siblings. Here,
// if u and v have the same parent, we say u is a sibling of v (vice versa).

// The height of a node in a tree is the number of edges on the longest simple
// downward path from the node to a leaf.

// Here, the given binary tree consists of n nodes and evey node has a unique ID
// from 0 to n-1.

// Input
// The first line of the input includes an integer n, the number of nodes of the
// tree.

// In the next n lines, the information of each node is given in the following
// format:

// id left right

// id is the node ID, left is ID of the left child and right is ID of the right
// child. If the node does not have the left (right) child, the left(right) is
// indicated by -1.

// Output
// Print the information of each node in the following format:

// node id: parent = p , sibling = s , degree = deg, depth = dep, height = h,
// type

// p is ID of its parent. If the node does not have a parent, print -1.

// s is ID of its sibling. If the node does not have a sibling, print -1.

// deg, dep and h are the number of children, depth and height of the node
// respectively.

// type is a type of nodes represented by a string (root, internal node or leaf.
// If the root can be considered as a leaf or an internal node, print root.

// Please follow the format presented in a sample output below.

// Constraints
// 1 ≤ n ≤ 25

typedef struct NODE {
  int id;
  int left;
  int right;
  int parent;
  int sib;    // If two nodes have the same parent, they are siblings.
  int degree; // the number of children
  int depth;  // root is 0, children of root is 1, and so on...
  int height; // The height of a node in a tree is
              // the number of edges on the longest simple downward path from
              // the node to a leaf.
  char type;  // i | l | r もし r && i => rootと出力、rも同様
} Node;

int n;
int root;
Node nodes[25];
int sibs[25];
int parentOf[25];
vector<int> leafs;

int storeSib(int l, int r) {
  int deg;
  if (l != -1 && r != -1) {
    sibs[l] = r;
    sibs[r] = l;
    deg = 2;
  } else if ((l != -1 && r == -1) || (l == -1 && r != -1)) {
    deg = 1;
  } else {
    deg = 0;
  }
  return deg;
}

Node newNode(int id, int l, int r) {
  Node node;
  node.id = id;
  node.left = l;
  node.right = r;
  // node.parent = -1;

  parentOf[l] = id;
  parentOf[r] = id;

  node.depth = 0;
  node.height = 0;

  node.sib = -1; // 後に更新する必要あり

  int deg = storeSib(l, r);
  node.degree = deg;

  if (deg > 0) {
    node.type = 'i'; // 後に更新する必要あり
  } else {
    node.type = 'l';
    leafs.push_back(id);
  }
  return node;
}

void store() {
  int id, left, right;
  for (int i = 0; i < n; i++) {
    cin >> id >> left >> right;
    nodes[id] = newNode(id, left, right);
  }
}

void init() {
  for (int i = 0; i < n; i++) {
    sibs[i] = -1;
    parentOf[i] = -1;
  }
}

string typeStr(char c) {
  if (c == 'i') {
    return "internal node";
  } else if (c == 'l') {
    return "leaf";
  } else if (c == 'r') {
    return "root";
  }
  return "";
}

void printBiTree() {
  // node id: parent = p , sibling = s , degree = deg, depth = dep, height = h,
  // type
  for (int i = 0; i < n; i++) {
    Node node = nodes[i];
    cout << "node " << node.id;
    cout << ": parent = " << node.parent;
    cout << ", sibling = " << node.sib;
    cout << ", degree = " << node.degree;
    cout << ", depth = " << node.depth;
    cout << ", height = " << node.height;
    cout << ", " << typeStr(node.type) << endl;
  }
}

void solveSibling() {
  for (int i = 0; i < n; i++) {
    if (sibs[i] != -1) {
      nodes[i].sib = sibs[i];
    }
  }
}

void solveParent() {
  for (int i = 0; i < n; i++) {
    nodes[i].parent = parentOf[i];
  }
}

void searchRoot() {
  for (int i = 0; i < n; i++) {
    int p = nodes[i].parent;
    if (p == -1) {
      root = i;
      nodes[i].type = 'r';
      return;
    }
  }
}

void calcEachNodeHeight(int id, int h) {
  int p = nodes[id].parent;
  if (p != -1) {
    nodes[p].height = max(h, nodes[p].height);
    calcEachNodeHeight(p, h + 1);
  }
}

void calcHeight() {
  for (int i = 0; i < leafs.size(); i++) {
    int l = leafs[i];
    calcEachNodeHeight(l, 1);
  }
}

void calcDepth(int id, int d) {
  nodes[id].depth = d;
  if (nodes[id].degree > 0) {
    if (nodes[id].left != -1) {
      calcDepth(nodes[id].left, d + 1);
    }
    if (nodes[id].right != -1) {
      calcDepth(nodes[id].right, d + 1);
    }
  }
}

int main() {
  cin >> n;
  init();

  store();

  solveSibling();
  solveParent();
  searchRoot();
  calcHeight();
  calcDepth(root, 0);

  printBiTree();
  return 0;
}


Error: 0

Fixed submission:

#include <cmath>
#include <iomanip>
#include <iostream>
#include <math.h>
#include <string>
#include <vector>
using namespace std;

typedef struct NODE {
  int id;
  int left_id;
  int right_id;
  struct NODE *left;
  struct NODE *right;
  int parent;
  int sibling;
  int child_num;
  int depth;
  int height;
  string type;
} node;

int n;
int root_id;
node **nodes;
vector<int> same_height;

void gen_node(int id, int left_id, int right_id) {
  node *p = (node *)malloc(sizeof(node));
  p->id = id;
  p->left_id = left_id;
  p->right_id = right_id;

  nodes[id] = p;
}

void connect_parent_child() {
  node *p = (node *)malloc(sizeof(node));
  node *q = (node *)malloc(sizeof(node));
  for (int i = 0; i < n; i++) {
    p = nodes[i];
    int l = p->left_id;
    int r = p->right_id;
    int child_num = 0;
    if (l != -1) {
      child_num++;
      p->left = (node *)malloc(sizeof(node));
      q = nodes[l];
      p->left = q;
      q->parent = p->id;
      if (r != -1) {
        q->sibling = r;
      }
    }
    if (p->right_id != -1) {
      child_num++;
      p->right = (node *)malloc(sizeof(node));
      q = nodes[r];
      p->right = q;
      q->parent = p->id;
      if (l != -1) {
        q->sibling = l;
      }
    }
    p->child_num = child_num;
    if (p->child_num > 0) {
      p->type = "internal node";
    }
    if (p->child_num == 0) {
      p->type = "leaf";
      p->height = 0;
      same_height.push_back(p->id);
    }
  }
}

void find_root() {
  for (int i = 0; i < n; i++) {
    if (nodes[i]->parent == -1) {
      nodes[i]->type = "root";
      root_id = nodes[i]->id;
      return;
    }
  }
}

void calc_depth(int id, int d) {
  nodes[id]->depth = d;
  if (nodes[id]->left_id != -1) {
    calc_depth(nodes[id]->left_id, d + 1);
  }
  if (nodes[id]->right_id != -1) {
    calc_depth(nodes[id]->right_id, d + 1);
  }
}

vector<int> calc_height(vector<int> s_h, int h) {
  vector<int> next_height;
  for (int i = 0; i < s_h.size(); i++) {
    if (nodes[s_h[i]]->parent != -1) {
      nodes[nodes[s_h[i]]->parent]->height = h;
      next_height.push_back(nodes[s_h[i]]->parent);
    }
  }
  return next_height;
}

void print_tree() {
  for (int i = 0; i < n; i++) {
    cout << "node " << nodes[i]->id << ": parent = " << nodes[i]->parent
         << ", sibling = " << nodes[i]->sibling
         << ", degree = " << nodes[i]->child_num
         << ", depth = " << nodes[i]->depth << ", height = " << nodes[i]->height
         << ", " << nodes[i]->type << endl;
  }
}

int main() {
  cin >> n;
  nodes = (node **)malloc(sizeof(node) * n);

  int id, left_id, right_id;
  for (int i = 0; i < n; i++) {
    cin >> id >> left_id >> right_id;
    gen_node(id, left_id, right_id);

    nodes[id]->parent = -1;
    nodes[id]->sibling = -1;
    nodes[id]->depth = -1;
    nodes[id]->height = -1;
  }

  connect_parent_child();

  find_root();

  nodes[root_id]->depth = 0;
  if (nodes[root_id]->left_id != -1) {
    calc_depth(nodes[root_id]->left->id, 1);
  }
  if (nodes[root_id]->right_id != -1) {
    calc_depth(nodes[root_id]->right->id, 1);
  }

  vector<int> next_height = same_height;

  int h = 1;
  while (next_height.size() > 0) {
    next_height = calc_height(next_height, h);
    h++;
  }

  print_tree();

  return 0;
}