This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub granddaifuku/library
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_C&lang=en" #include <bits/stdc++.h> using namespace std; #include "../../Graph/lowest_common_ancestor.cpp" int main() { int n, q; cin >> n; LCA<int> lca = LCA<int>(n); for (int i = 0; i < n; ++i) { int k; cin >> k; for (int j = 0; j < k; ++j) { int c; cin >> c; lca.addEdge(i, c); } } lca.init(); cin >> q; for (int i = 0; i < q; ++i) { int u, v; cin >> u >> v; cout << lca.query(u, v) << endl; } return 0; }
#line 1 "test/aoj/GRL_5_C.test.cpp" #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_C&lang=en" #include <bits/stdc++.h> using namespace std; #line 1 "Graph/lowest_common_ancestor.cpp" #line 5 "Graph/lowest_common_ancestor.cpp" using namespace std; template <typename T> class LCA { public: int n, log_v = 0; vector<int> depth; vector<T> costs; vector<vector<int> > to; vector<vector<T> > cost; vector<vector<int> > parent; LCA() {} LCA(int n_): n(n_) { while ((1 << log_v) < n) ++log_v; depth.assign(n, 0); costs.assign(n, 0); to = vector<vector<int> >(n); cost = vector<vector<T> >(n); parent = vector<vector<int> >(log_v, vector<int>(n, 0)); } void init(int root = 0) { dfs(root); for (int i = 0; i < log_v - 1; ++i) { for (int j = 0; j < n; ++j) parent[i + 1][j] = parent[i][parent[i][j]]; } } void addEdge(int u, int v, T c = 0) { to[u].push_back(v); to[v].push_back(u); cost[u].push_back(c); cost[v].push_back(c); } void dfs(int v, int p = -1, int d = 0, T c = 0) { if (p != -1) parent[0][v] = p; depth[v] = d; costs[v] = c; for (int i = 0; i < to[v].size(); ++i) { int e = to[v][i]; if (e == p) continue; dfs(e, v, d + 1, c + cost[v][i]); } } int query(int u, int v) { if (depth[u] > depth[v]) swap(u, v); for (int i = 0; i < log_v; ++i) { if ((depth[v] - depth[u]) >> i & 1) v = parent[i][v]; } if (u == v) return u; for (int i = log_v - 1; i >= 0; --i) { if (parent[i][u] != parent[i][v]) { u = parent[i][u]; v = parent[i][v]; } } return parent[0][u]; } int length(int u, int v) { return depth[u] + depth[v] - 2 * depth[query(u, v)]; } T dist(int u, int v) { return costs[u] + costs[v] - 2 * costs[query(u, v)]; } // is x on the path u - v bool isOnPath(int u, int v, int x) { return length(u, x) + length(v, x) == length(u, v); } }; #line 8 "test/aoj/GRL_5_C.test.cpp" int main() { int n, q; cin >> n; LCA<int> lca = LCA<int>(n); for (int i = 0; i < n; ++i) { int k; cin >> k; for (int j = 0; j < k; ++j) { int c; cin >> c; lca.addEdge(i, c); } } lca.init(); cin >> q; for (int i = 0; i < q; ++i) { int u, v; cin >> u >> v; cout << lca.query(u, v) << endl; } return 0; }