lca的两种求解方法(log)

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。


 

倍增法求lca

 

for(int i=1;i<=n;i++)lg[i]=lg[i-1]+(1<<lg[i-1]==i);

int lca(int x,int y){
    if(h[x]<h[y])swap(x,y);
    while(h[x]>h[y])x=f[x][lg[h[x]-h[y]]-1];
    if(x==y)return x;
    for(int i=lg[h[x]]-1;i>=0;i--)
        if(f[x][i]!=f[y][i]){
            x=f[x][i];
            y=f[y][i];
        }
    return f[x][0];
}

 

posted @ 2020-01-16 21:27  Mmasker  阅读(170)  评论(0编辑  收藏  举报