• LCA 在线倍增法 求最近公共祖先


    第一步:建树  这个就不说了

    第二部:分为两步  分别是深度预处理和祖先DP预处理

    DP预处理:

    int i,j;
         for(j=1;(1<<j)<n;j++)
           for(int i=0;i<n;++i)
            if(fa[i][j]=-1)
              fa[i][j]=fa[fa[i][j-1]][j-1];/*DP处理出i的2^j祖先是谁*/

    深度预处理:

    1 void dfs(int now,int from,int deepth)
    2 {
    3      deep[now]=deepth;
    4      for(int i=head[now];i;i=e[i].pre)
    5        if(e[i].v!=from)
    6          dfs(e[i].v,now,deepth+1);
    7 }

    第三部分:LCA核心

     1 int LCA(int a,int b)// 求a、b的最近公共祖先 
     2 {
     3     int i,j;
     4     if(deep[a]<deep[b]) swap(a,b); // 保证a的深度比b大这样便于操作 
     5     for(i=0;(1<<i)<=deep[a];++i);// (1<<i) 等同于2的i次方 
     6          i--;
     7     for(j=i;j>=0;j--)
     8       if((deep[a]-(1<<j))>=deep[b])// 让a节点往上蹦 直到a、b晚上一蹦就重合 
     9         a=fa[a][j];
    10     if(a==b)return a;// 如果a的一个祖先恰好是b 
    11     for(j=i;j>=0;j--)
    12       if(fa[a][j]!=-1&&fa[a][j]!=fa[b][j])// 没有越界并且祖先不同  那么就让a,b同时往上蹦 
    13         {
    14           a=fa[a][j];
    15           b=fa[b][j];
    16         }
    17     return fa[a][0];
    18 }

     默写的代码:

     1 void DP {
     2     int i,j;
     3     for(int j=1; (1<<j)<n; j++) {
     4         for(int i=0; i<n; i++)
     5             if(fa[i][j]=-1)
     6                 fa[i][j]=fa[fa[i][j-1]][j-1];
     7     }
     8 }
     9 void dfs(int now,int deepth,int from) {
    10     deep[now]=deepth;
    11     for(int i=head[now]; i; i=e[i].next) {
    12         if(e[i].v!=from) {
    13             dfs(e[i].v,deepth+1,now);
    14         }
    15     }
    16 }
    17 int LCA(int a,int b) {
    18     int i,j;
    19     if(deep[a]<deep[b]) swap(a,b);
    20     for(i=0; (1<<i)<=deep[a]; i++);
    21     i--;
    22     for(j=i; j>=0; j--) {
    23         if(deep[a]-(1<<j)>=deep[b])
    24             a=fa[a][j];
    25     }
    26     if(a==b) return a;
    27     for(j=i; j>=0; j--) {
    28         if(fa[a][j]!=-1&&fa[a][j]!=fa[b][j]) {
    29             a=fa[a][j];
    30             b=fa[b][j];
    31         }
    32     }
    33     return fa[a][0];
    34 }
  • 相关阅读:
    第四周PLECS仿真
    三相异步电动机预习笔记
    第三周PLECS仿真
    《自动化技术中的进给电气传动》 1.3节及《控制系统设计指南》 第一,二章设计指南读书笔记
    第二周 PLECS仿真
    机电传动课程学习
    《实时控制软件设计》2017年度教学总结
    《实时控制软件设计》2017年教学内容
    《机电传动控制》(2017)综合作业
    《机电传动控制》(2017)第十一周作业
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6103780.html
Copyright © 2020-2023  润新知