zoukankan      html  css  js  c++  java
  • 模板 树上求LCA 倍增和树链剖分

    //233

    模板 LCA
    void dfs(int x,int f){
        for(int i=0;i<E[x].size();i++){
            int v = E[x][i];
            if(v==f)continue;
            deep[v]=deep[x]+1;
            lca[v][0]=x;
            for(int j=1;j<maxm;j++){
                int fa = lca[v][j-1];
                if(fa==0)continue;
                lca[v][j]=lca[fa][j-1];
            }
            dfs(v,x);
        }
    }
    int up(int x,int d)
    {
        for(int i=maxm-1;i>=0;i--)
        {
            if(d<(1<<i))continue;
            x=lca[x][i];
            d-=(1<<i);
        }
        return x;
    }
    int Lca(int x,int y)
    {
        if(deep[x]>deep[y])swap(x,y);
        y=up(y,deep[y]-deep[x]);
        if(x==y)return x;
        for(int i=maxm-1;i>=0;i--)
        {
            if(lca[x][i]!=lca[y][i])
                x=lca[x][i],y=lca[y][i];
        }
        return lca[x][0];
    }
    
    //树链剖分
    #include <cstdio>
    #include <cstdlib>
    #define maxm 200010
    struct edge{int to,len,next;}E[maxm];
    int cnt,last[maxm],fa[maxm],top[maxm],deep[maxm],siz[maxm],son[maxm],val[maxm];
    void addedge(int a,int b,int len=0)
    {
        E[++cnt]=(edge){b,len,last[a]},last[a]=cnt;
    }
    void dfs1(int x)
    {
        deep[x]=deep[fa[x]]+1;siz[x]=1;
        for(int i=last[x];i;i=E[i].next)
        {
            int to=E[i].to;
            if(fa[x]!=to&&!fa[to]){
                val[to]=E[i].len;
                fa[to]=x;
                dfs1(to);
                siz[x]+=siz[to];
                if(siz[son[x]]<siz[to])son[x]=to;
            }
        }
    }
    void dfs2(int x)
    {
        if(x==son[fa[x]])top[x]=top[fa[x]];
        else top[x]=x;
        for(int i=last[x];i;i=E[i].next)if(fa[E[i].to]==x)dfs2(E[i].to);
    }
    void init(int root){dfs1(root),dfs2(root);}
    int query(int x,int y)
    {
        for(;top[x]!=top[y];deep[top[x]]>deep[top[y]]?x=fa[top[x]]:y=fa[top[y]]);
        return deep[x]<deep[y]?x:y;
    }
    int n,m,x,y,v;
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);addedge(x,y,v);addedge(y,x,v);
        }
        init(1);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            printf("%d
    ",query(x,y));
        }
        return 0 ;
    }
  • 相关阅读:
    CDQ分治
    2-sat
    整体二分
    apache性能优化
    apache反向代理出现502调整
    hadoop学习笔记肆--元数据管理机制
    ssh 免密码登录配置,及其原理
    extjs 中的一些鲜为人知的属性(深渊巨坑)
    hadoop学习笔记叁--简单应用
    hadoop学习笔记贰 --HDFS及YARN的启动
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5755489.html
Copyright © 2011-2022 走看看