1. 程式人生 > >洛谷3379 倍增求LCA

洛谷3379 倍增求LCA

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const ll maxn=500010;
ll n,m,s,x,y,a,b,cnt=0,N;
ll f[maxn][30],head[maxn],dept[maxn];
struct Edge{
    ll next,to;
}cute[maxn<<1];

void build(ll x,ll y)
{
    cute[
++cnt].next=head[x]; cute[cnt].to=y; head[x]=cnt; } void pre() { for(ll i=1;i<=N;i++) for(ll j=1;j<=n;j++) f[j][i]=f[f[j][i-1]][i-1]; } void dfs(ll x) { for(ll i=head[x];i;i=cute[i].next) { ll y=cute[i].to; if(f[x][0]!=y) { f[y][
0]=x; dept[y]=dept[x]+1; dfs(y); } } } ll lca(ll x,ll y) { if(dept[x]>dept[y]) swap(x,y); ll t=dept[y]-dept[x]; for(ll i=N;i>=0;i--) if(t&(1<<i)) y=f[y][i]; if(x==y) return x; for(ll i=N;i>=0;i--) { if(f[x][i]!=f[y][i]) { x
=f[x][i]; y=f[y][i]; } } return f[x][0]; } int main() { scanf("%lld%lld%lld",&n,&m,&s); for(ll i=1;i<=n-1;i++) { scanf("%lld%lld",&x,&y); build(x,y); build(y,x); } N=log2(n); dept[s]=1; f[s][0]=0; dfs(s); pre(); for(ll i=1;i<=m;i++) { scanf("%lld%lld",&a,&b); printf("%lld\n",lca(a,b)); } return 0; }