zoukankan      html  css  js  c++  java
  • Tarjan-LCA算法小记

    Tarjan-LCA算法是一种离线算法。

    算法描述:

    DFS遍历每个节点,对于遍历到的当前节点u:

    ①建立以u为代表元素的集合。

    ②遍历与u相连的节点v,如果没有被访问过,对于v使用Tarjan-LCA算法,结束后,将v的集合并入u的集合。

    ③对于与u有关的询问Query(u,v),如果v被访问过,则LCA(u,v)为v所在集合的代表元素。

    代码模板:

    const int maxn=10005; //节点数
    const int maxm=10005; //边数
    const int maxq=10005; //查询数
    
    int par[maxn];
    int find(int x){return (par[x]==x)?x:(par[x]=find(par[x]));}
    
    struct Edge{
        int u,v;
        Edge(int u=0,int v=0){this->u=u,this->v=v;}
    };
    vector<Edge> E;
    vector<int> Ge[maxn];
    void addedge(int u,int v)
    {
        E.push_back(Edge(u,v));
        Ge[u].push_back(E.size()-1);
    }
    
    struct Query{
        int u,v;
        int lca;
        Query(int u=0,int v=0,int lca=0){this->u=u,this->v=v,this->lca=lca;}
    };
    vector<Query> Q;
    vector<int> Gq[maxn];
    void addquery(int u,int v,int lca)
    {
        Q.push_back(Query(u,v,lca));
        Gq[u].push_back(Q.size()-1);
    }
    
    bool vis[maxn];
    void LCA(int u)
    {
        par[u]=u; //建立以u为代表元素的集合
        vis[u]=1;
        for(int i=0;i<Ge[u].size();i++)
        {
            Edge &e=E[Ge[u][i]]; int v=e.v;
            if(!vis[v])
            {
                LCA(v);
                par[v]=u; //将v的集合并入u的集合
            }
        }
        for(int i=0;i<Gq[u].size();i++)
        {
            Query &q=Q[Gq[u][i]]; int v=q.v;
            if(vis[v])
            {
                q.lca=find(v);
                Q[Gq[u][i]^1].lca=q.lca;
            }
        }
    }

    时间复杂度:

    DFS遍历图O(n),枚举查询O(q),总的就是O(n+q)。

  • 相关阅读:
    sqlalchemy 基本操作
    Codeforces 716A Crazy Computer
    Codeforces 719B Anatoly and Cockroaches
    POJ 1067 取石子游戏
    P1028 数的计算
    P1914 一串字母
    P1308 统计单词数
    P1200 你的飞碟在这儿
    P1055 书号
    P1567 气温统计
  • 原文地址:https://www.cnblogs.com/dilthey/p/9328406.html
Copyright © 2011-2022 走看看