这,大概是我在CSP前最后的一篇模板题了吧。
时隔一年,昨天又一次成功地打对了LCA,可海星。
这里用的是倍增的写法。
Code:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <queue> using namespace std; //Mystery_Sky // #define M 500001 #define INF 0x3f3f3f3f #define ll long long inline int read() { int x=0, f=1; char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } struct Edge{ int next, to; }edge[M<<1]; int n, m, cnt, t, s; int head[M], d[M], f[M][30]; queue <int> q; inline void add_edge(int u, int v) {edge[++cnt].to = v; edge[cnt].next = head[u]; head[u] = cnt;} inline void bfs() { d[s] = 1; q.push(s); while(!q.empty()) { int x = q.front(); q.pop(); for(int i = head[x]; i; i = edge[i].next) { int y = edge[i].to; if(d[y]) continue; d[y] = d[x] + 1; f[y][0] = x; for(int j = 1; j <= t; j++) f[y][j] = f[f[y][j-1]][j-1]; q.push(y); } } return; } inline int lca(int x, int y) { if(d[x] > d[y]) swap(x, y); for(int i = t; i >= 0; i--) if(d[f[y][i]] >= d[x]) y = f[y][i]; if(x == y) return x; for(int i = t; i >= 0; i--) if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i]; return f[x][0]; } int main() { n = read(), m = read(), s = read(); t = (int)(log(n) / log(2)); for(int i = 1; i <= n-1; i++) { int u = read(), v = read(); add_edge(u, v); add_edge(v, u); } bfs(); for(int i = 1; i <= m; i++) { int x = read(), y = read(); printf("%d\n", lca(x, y)); } return 0; }