zoukankan      html  css  js  c++  java
  • 树上倍增求LCA

    大概思想就是,节点$i$的第$2^{j}$个父节点是他第$2^{j-1}$个父亲的第$2^{j-1}$个父亲

    然后可以$O(nlogn)$时间内解决……

    没了?

     1 //fa[i][j]表示i的第2^j个父节点 
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 using namespace std;
     7 struct edge{
     8     int v,next;
     9 }a[100001];
    10 int n,q,u,v,rt,tot=0,head[100001],fa[100001][31],dep[100001];
    11 bool vis[100001];
    12 void add(int u,int v){
    13     a[++tot].v=v;
    14     a[tot].next=head[u];
    15     head[u]=tot;
    16 }
    17 void cal_dep(int u){
    18     vis[u]=true;
    19     for(int tmp=head[u];tmp!=-1;tmp=a[tmp].next){
    20         int v=a[tmp].v;
    21         if(!vis[v]){
    22             dep[v]=dep[u]+1;
    23             cal_dep(v);
    24         }
    25     }
    26 }
    27 void cal(){
    28     for(int j=1;j<=30;j++){
    29         for(int i=1;i<=n;i++){
    30             fa[i][j]=fa[fa[i][j-1]][j-1];
    31         }
    32     }
    33 }
    34 int lca(int x,int y){
    35     if(dep[x]<dep[y]){
    36         swap(x,y);
    37     }
    38     int s=dep[x]-dep[y];
    39     for(int i=0;i<30;i++){
    40         if((1<<i)&s)x=fa[x][i];
    41     } 
    42     if(x==y)return x;
    43     for(int i=29;i>=0;i--){
    44         if(fa[x][i]!=fa[y][i]){
    45             x=fa[x][i];
    46             y=fa[y][i];
    47         }
    48     }
    49     return fa[x][0];
    50 }
    51 int main(){
    52     memset(head,-1,sizeof(head));
    53     memset(fa,0,sizeof(fa));
    54     memset(dep,0,sizeof(dep));
    55     memset(vis,0,sizeof(vis));
    56     scanf("%d%d",&n,&q);
    57     for(int i=1;i<n;i++){
    58         scanf("%d%d",&u,&v);
    59         add(u,v);  
    60         fa[v][0]=u;
    61         //if(!fa[u][0])rt=u;
    62     }
    63     dep[1]=1;
    64     cal_dep(1);
    65     cal();
    66     for(int i=1;i<=q;i++){
    67         scanf("%d%d",&u,&v);
    68         printf("%d
    ",lca(u,v));
    69     }
    70     return 0;
    71 }
    72 /*
    73 16 4
    74 1 2
    75 1 3
    76 2 4
    77 2 5
    78 2 6
    79 3 7
    80 4 8
    81 4 9
    82 5 10
    83 7 11
    84 7 12
    85 10 13
    86 10 14
    87 10 15
    88 12 16
    89 4 7
    90 9 16
    91 11 16
    92 15 8
    93 ------
    94 1
    95 1
    96 7
    97 2
    98 */
  • 相关阅读:
    BZOJ 2588
    BZOJ 3524
    BZOJ 3932
    Bzoj1013--Jsoi2008球形空间产生器
    Codevs1743--反转卡片
    Bzoj1208--Hnoi2004宠物收养所
    Bzoj1112--Poi2008砖块Klo
    后缀自动机学习笔记
    Bzoj1588--Hnoi2002营业额统计
    Bzoj1056--Haoi2008排名系统
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/8952821.html
Copyright © 2011-2022 走看看