Language: C++

#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = (a); i < (int)(b); ++i)

using pii = pair<int, int>;
using vvi = vector<vector<int>>;
using vi  = vector<int>;
#define sz(x) ((int)x.size())

struct UnionFind {
    vi data;
    int comp;
    UnionFind() {}
    UnionFind(int size) {
        init(size);
    }
    void init(int size) {
        data.assign(size, -1);
        comp = size;
    }
    void unite(int x, int y) {
        x = root(x); y = root(y);
        if(x != y) {
            if(data[y] < data[x]) swap(x, y);
            data[x] += data[y];
            data[y] = x;
            comp--;
        }
    }
    bool same(int x, int y) {
        return root(x) == root(y);
    }
    int root(int x) {
        if (data[x] < 0) {
            return x;
        } else {
            return data[x] = root(data[x]);
        }
    }
    int size(int x) {
        return -data[root(x)];
    }
    int components() {
        return comp;
    }
};

struct LCA {
    using Query = pii;
    Graph g;
    vi color;
    vi ancestor;
    vector<vector<pair<int, Query>>> query_set;
    vi res;
    UnionFind uf;
    LCA(const vvi &g, vector<Query> &query) :
            g         (g),
            color     (sz(g)),
            ancestor  (sz(g)),
            query_set (sz(g)),
            res       (sz(query)),
            uf        (sz(g))
    {
        int qs = sz(query);
        rep(i, 0, qs) {
            query_set[query[i].first ].emplace_back(i, query[i]);
            query_set[query[i].second].emplace_back(i, query[i]);
        }
    }
    void visit(int v, int prev) {
        ancestor[uf.root(v)] = v;
        for (auto &w : g[v]) {
            if (w == prev) {
                continue;
            }
            visit(w, v);
            uf.unite(v, w);
            ancestor[uf.root(v)] = v;
        }
        color[v] = 1;
        for (auto &p : query_set[v]) {
            Query q = p.second;
            int w = (q.second == v ? q.first : (q.first == v ? q.second : -1));
            if (w == -1 || !color[w]) {
                continue;
            }
            res[p.first] = ancestor[uf.root(w)];
        }
    }
    vi solve(int root) {
        visit(root, -1);
        return res;
    }
};

signed main() {
    int N;
    cin >> N;
    vector<vector<int>> G(N);
    rep(v, 0, N) {
        int K;
        cin >> K;
        rep(k, 0, K) {
            int X;
            cin >> X;
            G[v].push_back(X);
        }
    }
    int Q;
    cin >> Q;
    vector<pii> queries;
    rep(i, 0, Q) {
        int U, V;
        cin >> U >> V;
        queries.emplace_back(U, V);
    }
    LCA<vvi> lca(G, queries);
    vi res = lca.solve(0);

    for (int ans : res) {
        cout << ans << endl;
    }
}



Compiler output:
a.cc:50:5: error: 'Graph' does not name a type
   50 |     Graph g;
      |     ^~~~~
a.cc: In constructor 'LCA::LCA(const vvi&, std::vector<std::pair<int, int> >&)':
a.cc:57:13: error: class 'LCA' does not have any field named 'g'
   57 |             g         (g),
      |             ^
a.cc: In member function 'void LCA::visit(int, int)':
a.cc:72:24: error: 'g' was not declared in this scope
   72 |         for (auto &w : g[v]) {
      |                        ^
a.cc: In function 'int main()':
a.cc:117:5: error: 'LCA' is not a template
  117 |     LCA<vvi> lca(G, queries);
      |     ^~~