zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    第二章 Flask——Flask中的request
    第一章 Flask——Flask简介
    第四章 Linux——Nginx环境部署指南
    众测平台
    jmeter进阶
    adb命令对app进行测试
    众测平台
    selenium
    java基础知识
    接口测试工具对比
  • 原文地址:https://www.cnblogs.com/cjjsb/p/8203882.html
Copyright © 2011-2022 走看看