• Luogu P3379 【模板】最近公共祖先(LCA)


      这就是一道很朴素的LCA题。

      算法应该主流的有三种:DFS序+RMQ;倍增;Tarjan;

      其中前面两个是在线算法,O(n log n),后一个是离线的,复杂度也是线性的O(n+q)。

      所以对于这道题n,q都偏大的情况下还是选择了Tarjan(后两种我不会)

      简单说一下Tarjan的思想,对整个树进行一次DFS,vis数组记录这个点是否被记录。

      对于每一个搜到的点,先查询所有要问的与它有关的点(就比如要求i,j,在搜到i或j的时候就要找到j或i),如果这个点被访问过了他们的LCA就是这个点的father(用并查集实现)。

      Why——? 

      因为如果这两个点都访问过了,那它们肯定在同一棵子树中(以根节点也算子树),那么由于j先被访问,因此它的祖先就是i,j的LCA。

      最后注意一下这是一棵树,所以总边数是n-1。

      提示一下在大牛分站交会有O2优化。

      CODE

    #include<cstdio>
    #include<vector>
    using namespace std;
    const int N=500005;
    vector <int> a[N],q[N],num[N];
    int father[N],ans[N],n,m,x,y,i,root;
    bool vis[N];
    inline void read(int &x)
    {
        x=0; char ch=getchar();
        while (ch<'0'||ch>'9') ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    }
    inline void write(int x)
    {
        if (x/10) write(x/10);
        putchar(x%10+'0');
    }
    inline int getfather(int k) { return father[k]==k?k:father[k]=getfather(father[k]); }
    inline void LCA(int k)
    {
        vis[k]=1;
        for (int i=0;i<q[k].size();++i)
        {
            int x=q[k][i];
            if (vis[x]) ans[num[k][i]]=getfather(x);
        }
        for (int i=0;i<a[k].size();++i)
        {
            int x=a[k][i];
            if (!vis[x]) LCA(x),father[x]=k;
        }
    }
    int main()
    {
        read(n); read(m); read(root);
        for (i=1;i<=n;++i)
        father[i]=i;
        for (i=1;i<=n-1;++i)
        {
            read(x); read(y);
            a[x].push_back(y); a[y].push_back(x);
        }
        for (i=1;i<=m;++i)
        {
            read(x); read(y);
            q[x].push_back(y); num[x].push_back(i);
            q[y].push_back(x); num[y].push_back(i);
        }
        LCA(root);
        for (i=1;i<=m;++i)
        write(ans[i]),putchar('
    ');
        return 0;
    }
  • 相关阅读:
    Asp.net Core依赖注入(Autofac替换IOC容器)
    .NET Core WEB API接口参数模型绑定
    .net core docker容器编排部署(linux)
    asp .net core发布订阅kafka
    asp.net Core依赖注入(自带的IOC容器)
    VS2017 GIT推送错误:Authentication failed解决办法
    《ASP.NET Core 开发实战》
    《Entity Framework 实用精要》
    《C# 敏捷开发实践》
    《ASP.NET 框架应用程序实战》
  • 原文地址:https://www.cnblogs.com/cjjsb/p/8203882.html
Copyright © 2020-2023  润新知