zoukankan      html  css  js  c++  java
  • 浅谈求lca

      lca即最近公共祖先,求最近公共祖先的方法大概有3种,其实是窝只听说过3种,这3种做法分别是倍增求lca,树剖求lca和tarjan求lca,但是窝只会前2种,所以这里只说前2种算法了。

      首先是倍增求lca,倍增求lca的思想是不断的向上跳,直到跳到lca为止

     

      比如求这棵树中x和y的lca,首先让深度较深的点(x)跳到和深度较浅(y)的点同一个深度,然后先看一下x和y是不是同一个点了,如果是,那么不用再向上跳了,返回x即可。如果不是,需要继续往上跳,而这个往上跳的过程是判断如果跳到的那个深度x和y的祖先不是同一个就可以往上跳,因为如果是同一个的话很有可能跳过了,由于是这样跳的,所以最后x和y跳到的点是兄弟,这时只需要返回他们的父亲就好了。跳的过程相当于是对lca与x,y的深度差二进制分解,只不过不知道这个数是什么罢了。

    模板:https://www.luogu.org/problemnew/show/P3379

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 const int maxn=500005; 
     5 int n,m,s; 
     6 int x,y;
     7 struct zhw{
     8     int to,last;
     9 }tu[maxn<<1];
    10 int head[maxn],tot;
    11 void add(int x,int y)
    12 {
    13     tot++,tu[tot].last=head[x],head[x]=tot,tu[tot].to=y;
    14 }
    15 int fa[maxn][18],deep[maxn];
    16 void dfs(int x)
    17 {
    18     for(int i=1;i<=17;++i)fa[x][i]=fa[fa[x][i-1]][i-1];
    19     for(int i=head[x];i;i=tu[i].last)
    20     {
    21         if(tu[i].to!=fa[x][0])
    22         {
    23             fa[tu[i].to][0]=x,deep[tu[i].to]=deep[x]+1;
    24             dfs(tu[i].to);
    25         }
    26     }
    27 }
    28 int lca(int x,int y)
    29 {
    30     if(deep[x]<deep[y])swap(x,y);
    31     int t=deep[x]-deep[y];
    32     for(int i=17;i>=0;i--)
    33         if((1<<i)&t)x=fa[x][i];
    34     if(x==y)return x;
    35     for(int i=17;i>=0;i--)
    36     {
    37         if(fa[x][i]!=fa[y][i])
    38             x=fa[x][i],y=fa[y][i];
    39     }
    40     return fa[x][0];
    41 }
    42 int main()
    43 {
    44     scanf("%d%d%d",&n,&m,&s);
    45     for(int i=1;i<n;++i)
    46     {
    47         scanf("%d%d",&x,&y);
    48         add(x,y),add(y,x);
    49     }
    50     deep[s]=1;dfs(s);
    51     while(m--)
    52     {
    53         scanf("%d%d",&x,&y);
    54         printf("%d
    ",lca(x,y));
    55     }
    56     return 0;
    57 } 
    View Code

      树剖那个以后有空了在写QAQ

      

    知世故而不世故,处江湖而远江湖,才是最成熟的善良
  • 相关阅读:
    redis几种模式的部署(Windows下实现)
    servlet容器:jetty,Tomcat,JBoss
    redis三种模式对比
    Linux expect详解
    expect学习笔记及实例详解
    shell expect的简单实用
    【Spring Boot】内嵌容器
    java 怎么让打印信息换行?
    Java中的静态方法是什么?
    java的接口为什么不能实例化
  • 原文地址:https://www.cnblogs.com/yuelian/p/8746202.html
Copyright © 2011-2022 走看看