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

#include <bits/stdc++.h>
using namespace std;

const int MAX_N = 100001;

int D
    [MAX_N]; // (HL分解後にあるnodeとあるnodeが同じHeavyPathに含まれているかどうか)
int find(int a) { return a - D[a] ? (D[a] = find(D[a])) : a; }

struct node {
  int id;
  vector<int> to;
  int h; // 深さ
  int size;
  node() { h = -1; }
  bool operator<(const node &n) const { return h < n.h; }
};

struct HL_node {
  int h;
  vector<int> v; // sortされる
  int np;        // Light-edgeで結ばれた親
};

bool used[MAX_N];
int vid[MAX_N];
node G[MAX_N]; // 子への辺をもつ
HL_node HL[MAX_N];
int V; // 頂点数

int dfs(int id, int h) {
  if (G[id].h > -1)
    return 0;
  G[id].h = h;
  G[id].size = 1;
  for (int i = 0; i < (int)G[id].to.size(); i++) {
    G[id].size += dfs(G[id].to[i], h + 1);
    ;
  }
  if (G[id].size == 1)
    return G[id].size;
  for (int i = 0; i < (int)G[id].to.size(); i++) {
    if (G[id].size / 2 <= G[G[id].to[i]].size) {
      D[G[id].to[i]] = find(id);
      break;
    }
  }
  return G[id].size;
}

void HeavyLightDecomposition(int root) {
  for (int i = 0; i < V; i++)
    D[i] = i;
  memset(used, 0, sizeof(used));
  dfs(root, 0);
  sort(G, G + V);
  vector<int> vs; // after_hl
  for (int i = 0; i < V; i++)
    vid[G[i].id] = i;
  for (int i = 0; i < V; i++) {
    int now = G[i].id;
    used[now] = true;
    HL[find(now)].v.push_back(now);
    for (int j = 0; j < (int)G[vid[now]].to.size(); j++) {
      int to = G[vid[now]].to[j];
      if (used[to])
        continue;
      if (find(to) == find(now))
        continue;
      HL[find(to)].np = now;
      HL[find(to)].h = HL[find(now)].h + 1;
    }
  }
}

int HeavyLightLCA(int a, int b) {
  for (; HL[find(a)].h != HL[find(b)].h; HL[find(a)].h > HL[find(b)].h
                                             ? (a = HL[find(a)].np)
                                             : (b = HL[find(b)].np))
    ;
  for (; find(a) != find(b); a = HL[find(a)].np, b = HL[find(b)].np)
    ;
  return vid[a] < vid[b] ? a : b;
}

int main() {
  cin >> V;
  for (int i = 0; i < V; i++) {
    G[i].id = i;
    int k;
    cin >> k;
    for (int j = 0; j < k; j++) {
      int c;
      cin >> c;
      G[i].to.push_back(c);
    }
  }
  HeavyLightDecomposition(0);
  int Q;
  cin >> Q;
  for (int i = 0; i < Q; i++) {
    int u, v;
    cin >> u >> v;
    cout << HeavyLightLCA(u, v) << endl;
  }
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

const int MAX_N = 100001;

int D
    [MAX_N]; // (HL分解後にあるnodeとあるnodeが同じHeavyPathに含まれているかどうか)
int find(int a) { return a - D[a] ? (D[a] = find(D[a])) : a; }

struct node {
  int id;
  vector<int> to;
  int h; // 深さ
  node() { h = -1; }
  bool operator<(const node &n) const { return h < n.h; }
};

struct HL_node {
  int h;
  vector<int> v; // sortされる
  int np;        // Light-edgeで結ばれた親
};

bool used[MAX_N];
int vid[MAX_N];
node G[MAX_N]; // 子への辺をもつ
HL_node HL[MAX_N];
int V; // 頂点数

int dfs(int id, int h) {
  if (G[id].h > -1)
    return 0;
  G[id].h = h;
  vector<int> cs;
  int sum = 1;
  for (int i = 0; i < (int)G[id].to.size(); i++) {
    cs.push_back(dfs(G[id].to[i], h + 1));
    sum += cs.back();
  }
  if (sum == 1)
    return sum;
  for (int i = 0; i < (int)G[id].to.size(); i++) {
    if (sum / 2 <= cs[i]) {
      D[G[id].to[i]] = find(id);
      break;
    }
  }
  return sum;
}

void HeavyLightDecomposition(int root) {
  for (int i = 0; i < V; i++)
    D[i] = i;
  memset(used, 0, sizeof(used));
  dfs(root, 0);
  sort(G, G + V);
  vector<int> vs; // after_hl
  for (int i = 0; i < V; i++)
    vid[G[i].id] = i;
  for (int i = 0; i < V; i++) {
    int now = G[i].id;
    used[now] = true;
    HL[find(now)].v.push_back(now);
    for (int j = 0; j < (int)G[vid[now]].to.size(); j++) {
      int to = G[vid[now]].to[j];
      if (used[to])
        continue;
      if (find(to) == find(now))
        continue;
      HL[find(to)].np = now;
      HL[find(to)].h = HL[find(now)].h + 1;
    }
  }
}

int HeavyLightLCA(int a, int b) {
  for (; HL[find(a)].h != HL[find(b)].h; HL[find(a)].h > HL[find(b)].h
                                             ? (a = HL[find(a)].np)
                                             : (b = HL[find(b)].np))
    ;
  for (; find(a) != find(b); a = HL[find(a)].np, b = HL[find(b)].np)
    ;
  return vid[a] < vid[b] ? a : b;
}

int main() {
  cin >> V;
  for (int i = 0; i < V; i++) {
    G[i].id = i;
    int k;
    cin >> k;
    for (int j = 0; j < k; j++) {
      int c;
      cin >> c;
      G[i].to.push_back(c);
    }
  }
  HeavyLightDecomposition(0);
  int Q;
  cin >> Q;
  for (int i = 0; i < Q; i++) {
    int u, v;
    cin >> u >> v;
    cout << HeavyLightLCA(u, v) << endl;
  }
}