zoukankan      html  css  js  c++  java
  • tarjian求lca

    看了好多dalao的博客,就总结一下啦ovo

    tarjian算法很是神奇,它的作用是求lca。它是一种离线算法。

    在线是指输入一个询问输出一个结果。

    离线是将询问一次性输入,一起处理。

    tarjan它是将m个询问打乱顺序,在每个结点上挂上它的询问,利用dfs和并查集进行处理。

    对于一个结点u,如果要找(u,v)的lca,u和v的关系分为以下几种情况:

    (1)结点v在u的子树中,那么lca(u,v)=u;

     (2)  结点v不在u的子树中,那么v就在u子结点以外的结点中。v可能在u的爸爸的子树中,那么lca(u,v)=u的爸爸;

    (3)如果v不在u的爸爸的子树中,那么v可能在u的爸爸的爸爸的子树中,lca(u,v)=u的爸爸的爸爸;

    发现找爸爸的过程好像和并查集的操作很像哦.

    【代码】

    #include<bits/stdc++.h>
    using namespace std;
    #define N 10000
    vector<int>vec[N];
    vector<int>que[N];
    int dad[N],far[N],qx[N],qy[N];
    int n,m,x,y,ans[N];
    int f(int x)
    {
        return far[x]==x?x:far[x]=f(far[x]);    
    }
    void dfs(int x)
    {
        far[x]=x;
        for(int i=0;i<vec[x].size();i++)
        {
            if(dad[x]!=vec[x][i])
            {
                dad[vec[x][i]]=x;
                dfs(vec[x][i]);
            }
        }
        for(int i=0;i<que[x].size();i++)
        {
            if(dad[y=qx[que[x][i]]^qy[que[x][i]]]^x)//y是x结点的一个询问;x^x^y=y; 
            {
                ans[que[x][i]]=f(y);
            }
        }
        far[x]=dad[x];
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&x,&y);
            vec[x].push_back(y);
            vec[y].push_back(x);
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&qx[i],&qy[i]);
            que[qx[i]].push_back(i);//在每个结点上挂上它的询问是第几个询问; 
            que[qy[i]].push_back(i);
        }
        dfs(1);
        for(int i=1;i<=m;i++)
        {
            printf("%d ",ans[i]);//每个询问的答案’ 
        }
        return 0;
    }
  • 相关阅读:
    tensorflow1.0 矩阵相乘
    tensorflow1.0 变量加法
    python 给字典按值排序,同样适合于其他
    pytorch 孪生神经网络DNN
    python 利用numpy同时打乱列表的顺序,同时打乱数据和标签的顺序
    python os模块获取指定目录下的文件列表
    创建自定义ssl证书用于https
    使用Maven命令行下载依赖库
    JAVA入门各种API参考
    在centos 6.9 x64下安装code::blocks步骤
  • 原文地址:https://www.cnblogs.com/zzyh/p/6812209.html
Copyright © 2011-2022 走看看