倍增求lca
步骤:
1.前置准备:lg数组,depth数组,fa数组
2.若x与y不在同一深度,先让它们跳到同一深度
3.开始倍增往上跳
代码:
#include<iostream> #include<cstdio> using namespace std; const long long N=1e6+10; int n,m,s,h1,h2,lg[N],fa[500010][30],depth[N]; int tot=0,head[N],nxt[N],v[N]; void add(int x,int y){ tot++; v[tot]=y; nxt[tot]=head[x]; head[x]=tot; } void dfs(int now,int fath){ fa[now][0]=fath; depth[now]=depth[fath]+1; for(int i=1;i<=lg[depth[now]];i++){ fa[now][i]=fa[fa[now][i-1]][i-1]; } for(int i=head[now];i;i=nxt[i]){ if(v[i]!=fath) dfs(v[i],now); } } int lca(int x,int y){ if(depth[x]<depth[y]) swap(x,y); while(depth[x]>depth[y]){ x=fa[x][lg[depth[x]-depth[y]]-1]; } if(x==y) return x; for(int i=lg[depth[x]]-1;i>=0;i--){ if(fa[x][i]!=fa[y][i]){ x=fa[x][i]; y=fa[y][i]; } } return fa[x][0]; } int main(){ scanf("%d%d%d",&n,&m,&s); for(int i=1;i<=n;i++){ lg[i]=lg[i-1]+(1<<lg[i-1]==i); } for(int i=1;i<n;i++){ scanf("%d%d",&h1,&h2); add(h1,h2); add(h2,h1); } dfs(s,0); for(int i=1;i<=m;i++){ scanf("%d%d",&h1,&h2); printf("%d\n",lca(h1,h2)); } return 0; }