#include<iostream>#include<cstdio>#define MAX 500001usingnamespace std;voidprint(int x){while(!x){return;}print(x/10);putchar(x%10+'0');}voidread(int&x){char c =getchar();while(!isdigit(c)){
c =getchar();}
x =0;while(c<='9'&& c>='0'){
x = x*10+ c-'0';
c =getchar();}}int n, m, s;int head[MAX], Next[MAX*2], vet[MAX*2], cnt;int d[MAX], f[MAX][20], lg[MAX];voidadd(int x,int y){
cnt++;
Next[cnt]= head[x];
head[x]= cnt;
vet[cnt]= y;}voidinit(){for(int i =1; i <= n; i++)
lg[i]= lg[i-1]+((1<<lg[i-1])==i);}voiddfs(int x,int fa){
d[x]= d[fa]+1;
f[x][0]= fa;for(int i =1;(1<<i)<=d[x]; i++)
f[x][i]= f[f[x][i-1]][i-1];//2^i = 2^(i-1)+2^(i-1)for(int i = head[x]; i; i = Next[i]){if(vet[i]!= fa)dfs(vet[i], x);}}inlineintLCA(int x,int y){if(d[x]< d[y])swap(x, y);while(d[x]> d[y])
x = f[x][lg[d[x]-d[y]]-1];if(x == y)return x;for(int i = lg[d[x]]-1; i >=0; i--){if(f[x][i]!= f[y][i]){
x = f[x][i];
y = f[y][i];}}return f[x][0];}intmain(){
cin >> n >> m >> s;int x, y;for(int i =1; i < n; i++){read(x);read(y);add(x, y);add(y, x);}init();dfs(s,0);for(int i =1; i <= m; i++){read(x);read(y);print(LCA(x, y));puts("");}return0;}
2. tarjan算法求LCA
代码:
#include<bits/stdc++.h>#define MAX 500005usingnamespace std;int n, m, s, cnt;int head[MAX], Next[MAX*2], vet[MAX*2];int qh[MAX], qnx[MAX*2], qv[MAX*2], ans[MAX*2], ord[MAX*2];int par[MAX];voidadd(int x,int y){
cnt++;
Next[cnt]= head[x];
head[x]= cnt;
vet[cnt]= y;}voidaddq(int x,int y){
cnt++;
qnx[cnt]= qh[x];
qh[x]= cnt;
qv[cnt]= y;}intfind(int x){if(par[x]== x){return x;}
par[x]=find(par[x]);return par[x];}voidconnect(int x,int y){int a =find(x), b =find(y);
par[a]= b;}bool vis[MAX];voidtarjan(int x,int fa){
vis[x]=true;for(int i = head[x]; i; i = Next[i]){int v = vet[i];if(!vis[v]&& v != fa){tarjan(v, x);connect(v, x);}}for(int i = qh[x]; i; i = qnx[i]){int v = qv[i];if(vis[v]){
ans[ord[i]]=find(v);}}}intmain(){
cin >> n >> m >> s;int x, y;for(int i =1; i < n; i++){scanf("%d %d",&x,&y);add(x, y);add(y, x);}
cnt =0;for(int i =1; i <= m; i++){scanf("%d %d",&x,&y);addq(x, y);
ord[cnt]= i;addq(y, x);
ord[cnt]= i;}for(int i =1; i <= n; i++){
par[i]= i;}tarjan(s,0);for(int i =1; i <= m; i++){printf("%d\n", ans[i]);}return0;}