LCA算法模板

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
#define MAXN 100010
#define INF 10000009
#define MOD 10000007
#define LL long long
#define in(a) a=read()
#define REP(i,k,n) for(int i=k;i<=n;i++)
#define DREP(i,k,n) for(int i=k;i>=n;i--)
#define cl(a) memset(a,0,sizeof(a))
inline int read(){
    int x=0,f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
    return x;
}
inline void out(int x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) out(x/10);
    putchar(x%10+'0');
}
int head[MAXN],to[MAXN],nxt[MAXN],f[MAXN],vis[MAXN];
int n,total=0,m;
queue <int> Q;
inline void adl(int a,int b){
    total++;
    to[total]=b;
    nxt[total]=head[a];
    head[a]=total;
    return  ;
}
struct node{
    int depth;
    int f[25];
}tree[MAXN];
inline void bfs(){
    vis[1]=1;
    tree[1].depth=0;
    Q.push(1);
    while(!Q.empty()){
        int u=Q.front();
        Q.pop();
        for(int e=head[u];e!=0;e=nxt[e])
            if(!vis[to[e]]){
                vis[to[e]]=1;
                tree[to[e]].f[0]=u;
                tree[to[e]].depth=tree[u].depth+1;
                Q.push(to[e]);
            }
    }
    return ;
}
inline void init(){
    for(int i=1;(1<<i)<=n;i++)
        REP(j,1,n)
            tree[j].f[i]=tree[tree[j].f[i-1]].f[i-1];
}
inline int lca(int u,int v){
    if(tree[u].depth<tree[u].depth)
        swap(u,v);
    int d=tree[u].depth-tree[v].depth;
    for(int i=0;(1<<i)<=d;i++)  if((1<<i) & d)  u=tree[u].f[i];
    if(u==v)  return u;
    for(int i=20;i>=0;i--)  if(tree[u].f[i]!=tree[v].f[i]){
        u=tree[u].f[i];
        v=tree[v].f[i];
    }
    return tree[u].f[0];
}
int main(){
    in(n);
    REP(i,1,n-1){
        int a,b;
        in(a);in(b);
        adl(a,b);
        adl(b,a);
    }
    bfs();
    init();
    REP(i,1,n){
        REP(j,0,2)
            cout<<tree[i].f[j]<<" ";
        cout<<endl;
    }
    REP(i,1,n)  printf("%d ",tree[i].depth);
    in(m);
    REP(j,1,m){
        int a,b;
        in(a);in(b);
        printf("%d\n",lca(a,b));
    }
    return 0;
}
/*
7
1 2
1 5
2 3
4 6
2 4
5 7
*/

猜你喜欢

转载自www.cnblogs.com/jason2003/p/9443602.html