• Tarjan离线求LCA


    上次貌似在处理RMQ问题时提起了倍增,这玩意可以求动态LCA(比较牛),现在我们在讲dfs时间戳的时候发现了一个求静态LCA的算法

    何为时间戳?

    在这里我们定义两个数组f和d,在深度优先搜索时记录这两个的值——f表示对这个店开始搜索的时间,d表示对这个店完成搜索的时间

    我们假设所有操作花费的都是单位时间,就可以得到一棵树的完整时间戳啦。

    这东西有什么用呢?

    对于树上任意两个和它们的LCA间的时间戳关系

    然后我们把所有询问都存下来

    我们发现其实两个点的LCA就是一个最“下面”的左边包含u,右边包含v的点。

    其实我们发现就是第一个还保持在u通往根的灰色状态的点(如果u,v属于同一个根的话)

    所以我们在dfs时顺带处理一下第一个灰色节点就行了

    模板题:POJ1330

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    const int N=10005;
    using namespace std;
    int n,i,u,v,a,b,rep[N],head[N],num,next[N],point[N],T;
    bool flag[N],FLAG[N];
    void make_way(int u,int v)
    {
        point[++num]=v;
        next[num]=head[u];
        head[u]=num;
    }
    int getrep(int u)
    {
        if(rep[u]==u)
        {
            return u;
        }
        return rep[u]=getrep(rep[u]);
    }
    void Init()
    {
        scanf("%d",&n);
        num=0;
        for(int i=1;i<=n;i++)
        head[i]=0,rep[i]=i,flag[i]=FLAG[i]0;
        for(int i=1;i<n;i++)
        {
            scanf("%d %d",&u,&v);
            FLAG[v]=1;
            make_way(u,v);
        }
        scanf("%d %d",&a,&b);
    }
    int findrt()
    {
        for(int i=1;i<=n;i++)
        if(!FLAG[i])
        {
            return i;
        }
    }
    void LCA(int u)
    {
        for(int i=head[u];i;i=next[i])
        {
            LCA(point[i]);
            //printf("i:%d rep:%d",point[i],rep[point[i]]);
            rep[rep[point[i]]]=u;
        }
        flag[u]=1;
        if(a==u&&flag[b])
        {
            cout<<getrep(b)<<endl;
        }else
        {
            if(b==u&&flag[a])
            cout<<getrep(a)<<endl;
        }
                
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            Init();
            LCA(findrt());
        }
    }    
  • 相关阅读:
    k8s 操作
    最大独立集!
    也许是二分
    P6624 [省选联考 2020 A 卷] 作业题
    USACO20 JAN&FEB P
    线性基
    SAM
    2 道用到同个贪心 trick 的题目
    C语言结构体字节对齐与Windows手动设置对齐#pragma pack
    【学习笔记】从Thread.start追踪Hotspot源码
  • 原文地址:https://www.cnblogs.com/dancer16/p/7097686.html
Copyright © 2020-2023  润新知