树上倍增求LCA(洛谷P3379)

#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
void in(int &x){
int y=1;char c=getchar();x=0;
while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
x*=y;
}
void o(int x) {
if (x < 0){
putchar('-');
x = -x;
}
if (x > 9)o(x / 10);
putchar(x % 10 + '0');
}
int read(){
int res=0;
int y=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
while(c<='9'&&c>='0'){res=(res<<1)+(res<<3)+c-'0';c=getchar();}
return res*y;
}
int n,m,s,t;
int a,b;//qr
vector<int>g[maxn];
void add(int fr,int to){
g[fr].push_back(to);
g[to].push_back(fr);
}
int f[maxn][30];
int depth[maxn];
void bfs(){
queue<int>q;
q.push(s);
depth[s]=1;
f[s][0]=s;
while (!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<g[u].size();i++){
int v=g[u][i];
if(depth[v])continue;
depth[v]=depth[u]+1;
f[v][0]=u;
for(int i=1;i<=t;i++){
f[v][i]=f[f[v][i-1]][i-1];
}
q.push(v);
}
}
}
int lca(int c,int d){
if(depth[c]>depth[d])swap(c,d);// depth d >= c
for(int i=t;i>=0;i--){
if(depth[f[d][i]]>=depth[c])d=f[d][i];
}
if(c==d)return c;
for(int i=t;i>=0;i--){
if(f[c][i]!=f[d][i]){
c=f[c][i];d=f[d][i];
}
}
return f[c][0];
}
signed main(){
in(n);in(m);in(s);
t=log2(n);
for(int i=1;i<=n-1;i++)add(read(),read());
bfs();
while(m--){
in(a);in(b);
o(lca(a,b));putchar('\n');
}
return 0;
}
posted @ 2020-10-13 16:06  yesuweiYYYY  阅读(97)  评论(0编辑  收藏  举报