1. 程式人生 > >LCA 倍增模板

LCA 倍增模板

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int ,int > pii;
const int N =100010;
const int DEG=20;

struct Edge
{
    int v;
    int next;
}edge[N*2];
int head[N],tot;
int fa[N][21];
int deg[N];

void init()
{
    memset(head,-1,sizeof(head));
    tot=0;
}
void adde(int u,int v)
{
    edge[++tot].v=v;
    edge[tot].next=head[u];
    head[u]=tot;
}
void bfs(int root)
{
    queue< int >que;
    deg[root]=0;
    que.push(root);
    while(!que.empty()){
        int tmp=que.front();
        que.pop();
        for(int i=1;i<DEG;i++)
            fa[tmp][i]=fa[fa[tmp][i-1]][i-1];
        for(int i=head[tmp];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(v==fa[tmp][0] ) continue;
            deg[v]=deg[tmp]+1;
            fa[v][0]=tmp;
            que.push(v);
        }
    }
}

int find_kfa(int x,int k)
{
    for(int i=0;i<DEG;i++){
        if((k>>i)&1) x=fa[x][i];
    }
    return x;
}

int LCA(int u,int v)
{
    if(deg[u]>deg[v]) swap(u,v);
    int hu=deg[u], hv=deg[v];
    int tu=u,tv=v;
    for(int det=hv-hu,i=0;det;det>>=1,i++){
        if(det&1) tv=fa[tv][i];
    }
    if(tu==tv) return tu;
    for(int i=DEG-1;i>=0;i--){
        if(fa[tu][i]==fa[tv][i]) continue;
        tu=fa[tu][i];
        tv=fa[tv][i];
    }
    return fa[tu][0];
}

int main()
{
    init();
    adde(1,2);
    adde(1,3);
    adde(3,4);
    adde(3,5);
    adde(4,7);
    adde(4,8);
    adde(4,9);
    adde(5,6);
    int rt=1;
    bfs(rt);
    cout<<"lca "<<LCA(7,9)<<" "<<LCA(3,7)<<" "<<LCA(6,3)<<endl;
    return 0;
}