Problem p02373 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cassert>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

struct LowestCommonAncestor {
  size_t n;
  size_t size() const { return n; }
  vector<int> color, parent, depth, topDepth, goUp, visited;
  vector<vector<int>> g;
  LowestCommonAncestor(size_t n_) : n(n_), g(n) {}
  void addEdge(int u, int v) {
    g[u].push_back(v);
    g[v].push_back(u);
  }
  void decomp(int root = 0, int B = 500) {
    parent.assign(n, -1);
    depth.assign(n, 0);
    topDepth.assign(n, 0);
    goUp.assign(n, -1);
    visited.assign(n, false);
    vector<int> tord;
    vector<int> q(n + 1);
    int l = 0, r = 0;
    q[r++] = root;
    while (l != r) {
      int v = q[l++];
      visited[v] = true;
      tord.push_back(v);
      for (int c : g[v]) {
        if (!visited[c]) {
          parent[c] = v;
          depth[c] = depth[v] + 1;
          q[r++] = c;
        }
      }
    }
    swap(color, visited); // ?????¢????????±??????
    color.assign(n, -1);
    int c = 0;
    for (int u : tord) {
      if (color[u] != -1)
        continue;
      l = 0, r = 0;
      q[r++] = u;
      for (int i = 0; i < B && l != r; i++) {
        int v = q[l++];
        color[v] = c;
        goUp[v] = parent[u];
        topDepth[v] = depth[u];
        for (int c : g[v])
          if (color[c] == -1)
            q[r++] = c;
      }
      c++;
    }
  }
  int solve(int u, int v) {
    while (topDepth[u] > topDepth[v])
      u = goUp[u];
    while (topDepth[u] < topDepth[v])
      v = goUp[v];
    while (depth[u] > depth[v])
      u = parent[u];
    while (depth[u] < depth[v])
      v = parent[v];
    while (u != v)
      u = parent[u], v = parent[v];
    return u;
  }
};

#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  int n;
  cin >> n;
  LowestCommonAncestor g(n);
  rep(i, n) {
    int k;
    cin >> k;
    rep(j, k) {
      int c;
      cin >> c;
      g.addEdge(i, c);
    }
  }
  g.decomp(0);
  int q;
  cin >> q;
  rep(i, q) {
    int u, v;
    cin >> u >> v;
    cout << g.solve(u, v) << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;

struct LowestCommonAncestor {
  size_t n;
  size_t size() const { return n; }
  vector<int> color, parent, depth, topDepth, goUp, visited;
  vector<vector<int>> g;
  LowestCommonAncestor(size_t n_) : n(n_), g(n) {}
  void addEdge(int u, int v) {
    g[u].push_back(v);
    g[v].push_back(u);
  }
  void decomp(int root = 0, int B = 500) {
    parent.assign(n, -1);
    depth.assign(n, 0);
    topDepth.assign(n, 0);
    goUp.assign(n, -1);
    visited.assign(n, false);
    vector<int> tord;
    vector<int> q(n + 1);
    int l = 0, r = 0;
    q[r++] = root;
    while (l != r) {
      int v = q[l++];
      visited[v] = true;
      tord.push_back(v);
      for (int c : g[v]) {
        if (!visited[c]) {
          parent[c] = v;
          depth[c] = depth[v] + 1;
          q[r++] = c;
        }
      }
    }
    swap(color, visited); // ?????¢????????±??????
    color.assign(n, -1);
    int c = 0;
    for (int u : tord) {
      if (color[u] == -1)
        continue;
      l = 0, r = 0;
      q[r++] = u;
      for (int i = 0; i < B && l != r; i++) {
        int v = q[l++];
        color[v] = c;
        goUp[v] = parent[u];
        topDepth[v] = depth[u];
        for (int c : g[v])
          if (color[c] != -1)
            q[r++] = c;
      }
      c++;
    }
  }
  int solve(int u, int v) {
    while (topDepth[u] > topDepth[v])
      u = goUp[u];
    while (topDepth[u] < topDepth[v])
      v = goUp[v];
    while (depth[u] > depth[v])
      u = parent[u];
    while (depth[u] < depth[v])
      v = parent[v];
    while (u != v)
      u = parent[u], v = parent[v];
    return u;
  }
};

#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  int n;
  cin >> n;
  LowestCommonAncestor g(n);
  rep(i, n) {
    int k;
    cin >> k;
    rep(j, k) {
      int c;
      cin >> c;
      g.addEdge(i, c);
    }
  }
  g.decomp(0);
  int q;
  cin >> q;
  rep(i, q) {
    int u, v;
    cin >> u >> v;
    cout << g.solve(u, v) << endl;
  }
}