处理链之后直接跑.不多说.
#pragma GCC target("f16c") #pragma GCC optimize("unroll-loops") #pragma GCC target("sse3","sse2","sse") #pragma GCC optimize(3,"Ofast","inline") #pragma GCC optimize("no-stack-protector") #pragma GCC target("avx","sse4","sse4.1","sse4.2","ssse3") #include<bits/stdc++.h> #define ll long long using namespace std; const int N=1e6+50; const int INF=0x3f; const double eps=1e-5; int n,m; int tot; int tim; int s,t; int f[N]; int ai[N]; int head[N]; int deep[N],size[N],bis[N],top[N],dfsx[N]; struct Edge { int u,v; } edge[N*3]; inline void add(int x,int y) { edge[++tot].u=head[x]; edge[tot].v=y; head[x]=tot; return ; } inline void dfs1(int now,int fa) { deep[now]=deep[fa]+1; size[now]=1; f[now]=fa; for(int i=head[now];i;i=edge[i].u){ int to=edge[i].v; if(to==fa) continue; dfs1(to,now); size[now]+=size[to]; if(size[to]>size[bis[now]]) bis[now]=to; } return ; } inline void dfs2(int now,int Top,int fa) { top[now]=Top; dfsx[now]=++tim; if(bis[now]) dfs2(bis[now],Top,now); for(int i=head[now];i;i=edge[i].u){ int to=edge[i].v; if(to==fa||to==bis[now]) continue ; dfs2(to,to,now); } return ; } inline int LCA(int x,int y){ while(top[x]!=top[y]){ if(deep[top[x]]<deep[top[y]]) swap(x,y); x=f[top[x]]; } if(deep[x]<deep[y]) swap(x,y); return y; } int main() { int root; scanf("%d%d%d",&n,&m,&root); for(int i=1;i<n;++i){ scanf("%d%d",&s,&t); add(s,t); add(t,s); } dfs1(root,0); dfs2(root,root,0); for(int i=1;i<=m;++i){ scanf("%d%d",&s,&t); printf("%d\n",LCA(s,t)); } return 0; }
原文:https://www.cnblogs.com/Fast-Bird/p/11816142.html