zoukankan      html  css  js  c++  java
  • 树链剖分求lca

    以poj 1330为例;

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<set>
    #include<map>
    using namespace std;
    #define LL long long
    #define pi (4*atan(1.0))
    #define eps 1e-8
    #define bug(x)  cout<<"bug"<<x<<endl;
    const int N=1e4+10,M=2e6+10,inf=1e9+10;
    const LL INF=1e18+10,mod=1e9+7;
    
    struct edge
    {
        int v,next;
    } edge[N<<1];
    int head[N<<1],edg,id,n;
    /// 树链剖分
    
    int fa[N],dep[N],son[N],siz[N]; // fa父亲,dep深度,son重儿子,siz以该点为子树的节点个数
    int a[N],ran[N],top[N],tid[N],du[N];  // tid表示边的标号,top通过重边可以到达最上面的点,ran表示标记tid
    void init()
    {
        memset(son,-1,sizeof(son));
        memset(head,-1,sizeof(head));
        memset(du,0,sizeof(du));
        edg=0;
        id=0;
    }
    
    void add(int u,int v)
    {
        edg++;
        edge[edg].v=v;
        edge[edg].next=head[u];
        head[u]=edg;
    }
    
    void dfs1(int u,int fath,int deep)
    {
        fa[u]=fath;
        siz[u]=1;
        dep[u]=deep;
        for(int i=head[u]; i!=-1; i=edge[i].next)
        {
            int v=edge[i].v;
            if(v==fath)continue;
            dfs1(v,u,deep+1);
            siz[u]+=siz[v];
            if(son[u]==-1||siz[v]>siz[son[u]])
                son[u]=v;
        }
    }
    
    void dfs2(int u,int tp)
    {
        tid[u]=++id;
        top[u]=tp;
        ran[tid[u]]=u;
        if(son[u]==-1)return;
        dfs2(son[u],tp);
        for(int i=head[u]; i!=-1; i=edge[i].next)
        {
            int v=edge[i].v;
            if(v==fa[u])continue;
            if(v!=son[u])
                dfs2(v,v);
        }
    }
    int lca(int l,int r)
    {
        while(top[l]!=top[r])
        {
            if(dep[top[l]]<dep[top[r]])swap(l,r);
            l=fa[top[l]];
        }
        if(dep[l]<dep[r])swap(l,r);
        return r;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            init();
            int n;
            scanf("%d",&n);
            for(int i=1;i<n;i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                add(u,v);
                add(v,u);
                du[v]++;
            }
            for(int i=1;i<=n;i++)
            if(!du[i])
            {
                dfs1(i,-1,1);
                dfs2(i,i);
                break;
            }
            int l,r;
            scanf("%d%d",&l,&r);
            printf("%d
    ",lca(l,r));
        }
        return 0;
    }
  • 相关阅读:
    大约 C++ 几个方面分析--overload, override, overwrite, rewrite
    Catalan数总结
    JAVA该队列中的数组,圆阵队列,链队列
    hdu4770:Lights Against Dudely(回溯 + 修剪)
    Birt
    Activity
    简单实现的Servlet文件上传,并显示
    阿里云centos 6.5 32位安装可视化界面的方法
    cannot mount database in EXCLUSIVE mode
    ORA-00845: MEMORY_TARGET not supported on this system
  • 原文地址:https://www.cnblogs.com/jhz033/p/7227972.html
Copyright © 2011-2022 走看看