树剖版lca

int FA[MAXN],dep[MAXN],sz[MAXN],son[MAXN],top[MAXN];
vector<int>G[MAXN];

void dfs1(int u,int fa){
    sz[u]=1; dep[u]=dep[fa]+1; FA[u]=fa;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==fa)continue;
        dfs1(v,u);
        sz[u]+=sz[v];
        if(sz[v]>sz[son[u]])son[u]=v;
    }
}

void dfs2(int u){
    if(son[u]){
        top[son[u]]=top[u];
        dfs2(son[u]);
    }
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(v==FA[u]||v==son[u])continue;
        top[v]=v;
        dfs2(v);
    }
}

int lca(int u,int v){
    while(top[u]!=top[v]){
        if(dep[top[u]]>dep[top[v]])swap(u,v);
        v=FA[top[v]];
    }
    if(dep[u]>dep[v])swap(u,v);
    return u;
}

这份模板需要首先对树上任意一点进行dfs1(rt);然后将top [ rt ] 设为1,之后再进行一遍dfs2(rt),然后通过输入求解lca。

原文地址:https://www.cnblogs.com/Mmasker/p/12203331.html