【学习/模板】倍增求LCA

  

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

   走过路过不要错过!!

  一文让你秒懂倍增求LCA!!

  看完不会不要钱!!

  会了也不要!!

 1 #include<bits/stdc++.h>
 2 #define maxn 500001
 3 using namespace std;
 4 int log2n,n,m,s;
 5 struct node{
 6     int next,to;
 7 }e[maxn<<1];
 8 int num,head[maxn],deep[maxn],jump[maxn][23];
 9 //num 边的编号 head[i]以i节点为起点的边(存树时是最后一条边,遍历时从第一条边开始遍历)
10 // deep[i] 节点i的深度 jump[i][j] 当前节点为i,向上跳2^j步可以到达的节点位置 
11 void add(int from,int to)//建树 
12 {
13     e[++num].next=head[from];
14     e[num].to=to;
15     head[from]=num;
16 }
17 void dfs(int u)//通过深搜确定每个节点的深度 
18 {
19     for(int i=head[u];i;i=e[i].next)//邻接表遍历 
20     {
21         int v=e[i].to;//边i以节点u为起点以节点v为终点 
22         if(v!=jump[u][0])//如果v不是u的父节点 
23         {
24             jump[v][0]=u;//那么v的父节点是u 
25             deep[v]=deep[u]+1;//所以v的深度比u的深度大一 
26             dfs(v);//继续搜QAQ 
27         }
28     }
29 }
30 void bzinit()//预处理出每个节点向上走2^i步可以走到的节点位置 
31 {
32     for(int i=1;i<=log2n;i++)//2^log2n==n i<=log2n可以保证跳不出n个节点 
33     {
34         for(int j=1;j<=n;j++)
35         {
36             jump[j][i]=jump[jump[j][i-1]][i-1]; 
37             //2^i-1+2^i-1==2*2^i-1==2^i 故上式成立  
38         }
39     }
40 }
41 int lca(int x,int y)//求最近公共祖先 
42 {
43     if(deep[x]<deep[y]) swap(x,y);//保证x的深度永远大于y的深度 
44     int t=deep[x]-deep[y];//xy之间的高度差 
45     for(int i=0;(1<<i)<=n;i++)
46     //从0开始 因为2^0=1 一步是最小的运动单位(1<<i)<=n保证了跳不出n个节点  
47     {
48         if(t&(1<<i))//&运算符 只有1&1==1 其余均为零 
49         {
50             x=jump[x][i];
51             //当高度差在二进制下,该位不为零时跳,保证了可以使两个节点先跳到同一高度差 
52             /*任何一个正整数都能被表示为一些2的n次方加起来
53             十进制:16=16        15=8+4+2+1          10=8+2        5=4+1        
54             二进制:10000=10000  1111=1000+100+10+1  1010=1000+10  101=100+1    */
55         }
56     }
57     if(x==y) return x; 
58     for(int i=log2n;i>=0;i--)
59     //开始跳时先大步跳,后小步跳,避免错过lca 
60     {
61         if(jump[x][i]!=jump[y][i])
62         //当从xy节点跳2^i步不相等时,证明还未找到lca,不存在错过的情况,可以跳 
63         {
64             x=jump[x][i];
65             y=jump[y][i];
66         }
67     }
68     return jump[x][0];
69     //当跳至lca以上时,节点相同,为避免这种情况,跳到lca深度加一的点,然后返回该节点的父节点,即lca;
70 }
71 int main()
72 {
73     int x,y;
74     cin>>n>>m>>s;
75     log2n=log(n)/log(2)+1;
76     for(int i=1;i<n;i++)
77     {
78         scanf("%d%d",&x,&y);
79         add(x,y);
80         add(y,x);//建两边图,可以向下建树向上查找之类的 
81     }
82     deep[s]=1;
83     jump[s][0]=0;
84     dfs(s);
85     bzinit();
86     for(int i=1;i<=m;i++)
87     {
88         scanf("%d%d",&x,&y);
89         printf("%d\n",lca(x,y));
90     }
91     return 0;    
92 }

 

这绝对是我写过有最详细注释的代码qwq

而且十分清晰易懂qwq

夸我!!

posted @ 2018-08-22 09:33  _Hwjia  阅读(239)  评论(1编辑  收藏  举报
                       ::                              ::
                      :;J7, :,                        ::;7:
                      ,ivYi, ,                       ;LLLFS:
                      :iv7Yi                       :7ri;j5PL
                     ,:ivYLvr                    ,ivrrirrY2X,
                     :;r@Wwz.7r:                :ivu@kexianli.
                    :iL7::,:::iiirii:ii;::::,,irvF7rvvLujL7ur
                   ri::,:,::i:iiiiiii:i:irrv177JX7rYXqZEkvv17
                ;i:, , ::::iirrririi:i:::iiir2XXvii;L8OGJr71i
              :,, ,,:   ,::ir@mingyi.irii:i:::j1jri7ZBOS7ivv,
                 ,::,    ::rv77iiiriii:iii:i::,rvLq@huhao.Li
             ,,      ,, ,:ir7ir::,:::i;ir:::i:i::rSGGYri712:
           :::  ,v7r:: ::rrv77:, ,, ,:i7rrii:::::, ir7ri7Lri
          ,     2OBBOi,iiir;r::        ,irriiii::,, ,iv7Luur:
        ,,     i78MBBi,:,:::,:,  :7FSL: ,iriii:::i::,,:rLqXv::
        :      iuMMP: :,:::,:ii;2GY7OBB0viiii:i:iii:i:::iJqL;::
       ,     ::::i   ,,,,, ::LuBBu BBBBBErii:i:i:i:i:i:i:r77ii
      ,       :       , ,,:::rruBZ1MBBqi, :,,,:::,::::::iiriri:
     ,               ,,,,::::i:  @arqiao.       ,:,, ,:::ii;i7:
    :,       rjujLYLi   ,,:::::,:::::::::,,   ,:i,:,,,,,::i:iii
    ::      BBBBBBBBB0,    ,,::: , ,:::::: ,      ,,,, ,,:::::::
    i,  ,  ,8BHWJBBBBBi     ,,:,,     ,,, , ,   , , , :,::ii::i::
    :      iZMOMAQBBM2::::::::::,,,,     ,,,,,,:,,,::::i:irr:i:::,
    i   ,,:;u0MBMOG1L:::i::::::  ,,,::,   ,,, ::::::i:i:iirii:i:i:
    :    ,iuUuuXUkFu7i:iii:i:::, :,:,: ::::::::i:i:::::iirr7iiri::
    :     :rk@Yizero.i:::::, ,:ii:::::::i:::::i::,::::iirrriiiri::,
     :      5BMBBBBBBSr:,::rv2kuii:::iii::,:i:,, , ,,:,:i@petermu.,
          , :r50EZ8MBBBBGOBBBZP7::::i::,:::::,: :,:,::i;rrririiii::
              :jujYY7LS0ujJL7r::,::i::,::::::::::::::iirirrrrrrr:ii:
           ,:  :@kevensun.:,:,,,::::i:i:::::,,::::::iir;ii;7v77;ii;i,
           ,,,     ,,:,::::::i:iiiii:i::::,, ::::iiiir@xingjief.r;7:i,
        , , ,,,:,,::::::::iiiiiiiiii:,:,:::::::::iiir;ri7vL77rrirri::
         :,, , ::::::::i:::i:::i:i::,,,,,:,::i:i:::iir;@Secbone.ii:::