题目:P3379
树上LCA,本蒟蒻罕见的一遍A掉的板子
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> using namespace std; inline int read() { int f=1,x=0; char ch=getchar(); while(ch<'0' || ch>'9') {if(ch=='-') f=-1; ch=getchar();} while(ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,m,s; int cnt; int head[500005],nxt[1000005],v[1000005]; int dep[500005],f[500005][21]; void add(int a,int b) { v[++cnt]=b; nxt[cnt]=head[a]; head[a]=cnt; } void dfs(int x,int fa) { dep[x]=dep[fa]+1; for(int i=0;i<=19;i++) f[x][i+1]=f[f[x][i]][i]; for(int i=head[x];i;i=nxt[i]) { int t=v[i]; if(t==fa) continue; f[t][0]=x; dfs(t,x); } } int LCA(int a,int b) { int i; if(dep[a]<dep[b]) { int t=a; a=b; b=t; } for(i=20;i>=0;i--) { if(dep[a]-(1<<i)>=dep[b]) a=f[a][i]; if(a==b) return a; } for(i=20;i>=0;i--) { if(f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i]; } return f[a][0]; } int main() { int i,a,b; n=read(); m=read(); s=read(); for(i=1;i<=n-1;i++) { a=read(); b=read(); add(a,b); add(b,a); } dfs(s,0); for(i=1;i<=m;i++) { a=read(); b=read(); printf("%d ",LCA(a,b)); } return 0; }