• 【树链剖分】洛谷P3379 树链剖分求LCA


    其实就是让两个点,看谁的深度大,谁就先跳。直到两个点的top顶点一致时,此时谁的深度小谁就是Lca.

    zz:https://www.cnblogs.com/rir1715/p/7668338.html

    树剖就是把树剖分成若干条不相交的链,目前常用做法是剖成轻重链

    所以我们定义siz[x]为以x为根结点的子树的结点个数

    对于每个结点x,在它的所有子结点中寻找一个结点y

    使得对于y的兄弟节点z,都有siz[y]≥siz[z]

    此时x就有一条重边连向y,有若干条轻边连向他的其他子结点【比如z】

    这样的话,树上的不在重链上的边的数量就会大大减少

    然后我们每次求LCA(x,y)的时候就可以判断两点是否在同一链上

    如果两点在同一条链上我们只要找到这两点中深度较小的点输出就行了

    如果两点不在同一条链上

    那就找到深度较大的点令它等于它所在的重链链端的父节点即为x=f[top[x]]

    直到两点到达同一条链上,输出两点中深度较小的点。

    //by 减维
    #include<cstdio>
    #include<iostream>
    using namespace std;
    struct edge{
        int to,ne;
    }e[1000005];
    int n,m,s,ecnt,head[500005],dep[500005],siz[500005],son[500005],top[500005],f[500005];
    void add(int x,int y)
    {
        e[++ecnt].to=y;
        e[ecnt].ne=head[x];
        head[x]=ecnt;
    }
    void dfs1(int x)
    {
        siz[x]=1;
        dep[x]=dep[f[x]]+1;
        for(int i=head[x];i;i=e[i].ne)
        {
            int dd=e[i].to;
            if(dd==f[x])continue;
            f[dd]=x;
            dfs1(dd);
            siz[x]+=siz[dd];
            if(!son[x]||siz[son[x]]<siz[dd])
                son[x]=dd;
        }
    }
    void dfs2(int x,int tv)
    {
        top[x]=tv;
        if(son[x])dfs2(son[x],tv);
        for(int i=head[x];i;i=e[i].ne)
        {
            int dd=e[i].to;
            if(dd==f[x]||dd==son[x])continue;
            dfs2(dd,dd);
        }
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&s);
        for(int i=1;i<n;++i)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs1(s);
        dfs2(s,s);
        for(int i=1;i<=m;++i)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            while(top[x]!=top[y]) //如果不在一条重链时 
            {
                if(dep[top[x]]>=dep[top[y]])x=f[top[x]];
                else y=f[top[y]];
            }
            printf("%d
    ",dep[x]<dep[y]?x:y);
        }
    }
    

      

  • 相关阅读:
    转载:关于sql server数据库表的主键问题
    centos FTP服务器的架设和配置
    OceanBase,淘宝开源的千亿级别分布式数据库系统。支持读写事务的线上服务
    在Fedora/Redhat/CentOS中防火墙设置
    转:SQL2008调试
    1.4.2 使用ActionScript类
    自写ajax经验总结
    搜索引擎中文分词技术
    优化数据库的方法及SQL语句优化的原则
    因为数据库正在使用,所以无法获得对数据库的独占访问权还原或删除数据库的解决方法
  • 原文地址:https://www.cnblogs.com/cutemush/p/11884770.html
Copyright © 2020-2023  润新知