zoukankan      html  css  js  c++  java
  • Latest Common Ancestor

    倍增求LCA

    时间复杂度O(nlogn)

    模板

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include<queue>
    using namespace std;
    
    const int maxn = 10007;
    const int DEG = 20;
    
    int head[maxn*2],nxt[maxn*2],to[maxn*2],tot;
    
    void init()
    {
        tot=0;
        memset(head,0,sizeof(head));
        memset(nxt,0,sizeof(nxt));
    }
    
    void add(int u,int v)
    {
        ++tot;
        to[tot]=v;
        nxt[tot]=head[u];
        head[u]=tot;
    }
    
    int fa[maxn][DEG];  //fa[i][j]表示结点i的第2^j个祖先
    int deg[maxn];      //深度数组
    
    void bfs(int root)
    {
        queue<int>que;
        deg[root]=0;
        fa[root][0]=root;
        que.push(root);
        while(!que.empty())
        {
            int tmp=que.front();
            que.pop();
            for(int i=1;i<DEG;i++)
                fa[tmp][i]=fa[fa[tmp][i-1]][i-1];
            for(int i=head[tmp];i;i=nxt[i])
            {
                int v=to[i];
                if(v==fa[tmp][0]) continue;
                deg[v]=deg[tmp]+1;
                fa[v][0]=tmp;
                que.push(v);
            }
        }
    }
    
    int LCA(int u,int v)
    {
        if(deg[u]>deg[v]) swap(u,v);
        int hu=deg[u],hv=deg[v];
        int tu=u,tv=v;
        for(int det=hv-hu,i=0;det;det>>=1,i++)
            if(det&1) tv=fa[tv][i];
        if(tu==tv) return tu;
        for(int i=DEG-1;i>=0;i--)
        {
            if(fa[tu][i]==fa[tv][i])
                continue;
            tu=fa[tu][i];
            tv=fa[tv][i];
        }
        return fa[tu][0];
    }
    
    bool flag[maxn];
    int main()
    {
        int tt,n,u,v;
        scanf("%d",&tt);
        while(tt--)
        {
            init();
            scanf("%d",&n);
            memset(flag,false,sizeof(flag));
            for(int i=1;i<n;i++)
            {
                scanf("%d%d",&u,&v);
                add(u,v),add(v,u);
                flag[v]=true;  // !!!!
            }
            int root;
            for(int i=1;i<=n;i++)
            {
                if(!flag[i])
                {
                    root=i;
                    break;
                }
            }
            bfs(root);
            scanf("%d%d",&u,&v);
            printf("%d
    ",LCA(u,v));
        }
        return 0;
    }
    

    POJ1330

    分析

    模板题


    SPOJ COT

    分析

    根据dfs序建主席树,lca求最近公共祖先结点后,正常的按照主席树查询第k大即可


  • 相关阅读:
    Scrapy+Scrapy-redis+Scrapyd+Gerapy 分布式爬虫框架整合
    centos7 安装软件指南
    Kafka--消费者
    Kafka--生产者
    Kafka--初识Kafka
    Kafka--Kafka简述
    NetWork--记一次Http和TLS抓包
    JVM--a == (a = b)基于栈的解释器执行过程
    Java容器--Queue
    Idea--使用Idea调试设置
  • 原文地址:https://www.cnblogs.com/Deadline/p/9041624.html
Copyright © 2011-2022 走看看