1. 程式人生 > >某演算法的板子練習(二)

某演算法的板子練習(二)

題目:P3379

 

樹上LCA,本蒟蒻罕見的一遍A掉的板子

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

inline int read()
{
    int f=1,x=0;
    char ch=getchar();
    while(ch<'0' || ch>'9') {if
(ch=='-') f=-1; ch=getchar();} while(ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} return x*f; } int n,m,s; int cnt; int head[500005],nxt[1000005],v[1000005]; int dep[500005],f[500005][21]; void add(int a,int b) { v[++cnt]=b; nxt[cnt]=head[a]; head[a]=cnt; } void dfs(int x,int fa) { dep[x]
=dep[fa]+1; for(int i=0;i<=19;i++) f[x][i+1]=f[f[x][i]][i]; for(int i=head[x];i;i=nxt[i]) { int t=v[i]; if(t==fa) continue; f[t][0]=x; dfs(t,x); } } int LCA(int a,int b) { int i; if(dep[a]<dep[b]) { int t=a; a=b; b=t; }
for(i=20;i>=0;i--) { if(dep[a]-(1<<i)>=dep[b]) a=f[a][i]; if(a==b) return a; } for(i=20;i>=0;i--) { if(f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i]; } return f[a][0]; } int main() { int i,a,b; n=read(); m=read(); s=read(); for(i=1;i<=n-1;i++) { a=read(); b=read(); add(a,b); add(b,a); } dfs(s,0); for(i=1;i<=m;i++) { a=read(); b=read(); printf("%d\n",LCA(a,b)); } return 0; }