洛谷 P3379 【模板】最近公共祖先(LCA)
阿新 • • 發佈:2020-10-26
傳送門
Version 1: 倍增
#include <bits/stdc++.h> using namespace std; using ll = long long; using p = pair<int, int>; const int maxn(5e5 + 10); const int maxm(1e6 + 10); int ecnt, head[maxn]; int dep[maxn], f[maxn][20]; struct edge { int to, nxt; } edges[maxm]; template<typename T = int> inline const T read() { T x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } return x * f; } template<typename T> inline void write(T x, bool ln) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x / 10, false); putchar(x % 10 + '0'); if (ln) putchar(10); } void addEdge(int u, int v) { edges[ecnt].to = v; edges[ecnt].nxt = head[u]; head[u] = ecnt++; } void bfs(int root) { queue<int> q; q.push(root); dep[root] = 1; while (not q.empty()) { int u = q.front(); q.pop(); for (int i = head[u]; compl i; i = edges[i].nxt) { int v = edges[i].to; if (dep[v]) { continue; } q.push(v); dep[v] = dep[u] + 1; f[v][0] = u; for (int j = 1; j < 20; ++j) { f[v][j] = f[f[v][j - 1]][j - 1]; } } } } int lca(int u, int v) { if (dep[u] < dep[v]) { swap(u, v); } for (int i = 19; i >= 0; --i) { if (dep[f[u][i]] >= dep[v]) { u = f[u][i]; } } if (u == v) { return u; } for (int i = 19; i >= 0; --i) { if (f[u][i] not_eq f[v][i]) { u = f[u][i]; v = f[v][i]; } } return f[u][0]; } int main() { #ifdef ONLINE_JUDGE #else freopen("input.txt", "r", stdin); #endif ios::sync_with_stdio(false); memset(head, -1, sizeof head); int n = read(), m = read(), s = read(); for (int i = 0; i < n - 1; ++i) { int u = read(), v = read(); addEdge(u, v); addEdge(v, u); } bfs(s); while (m--) { int u = read(), v = read(); write(lca(u, v), true); } return 0; }
Version 2: 離線 Tarjan