zoukankan      html  css  js  c++  java
  • LCA模板

    LCA就是最近公共祖先

    一个LCA的模板,代码作用注释写有

     1 int f[MAXN][30];//表示i往上跳2^j格所到的位置,后面还可以适当的增加维数去维护一些值
     2 int depth[MAXN];//表示i的深度
     3 void dfs(int st,int father,int depth){//利用dfs求出父亲节点以及i节点的深度 
     4     depth[st]=depth;fa[st][0]=father;
     5     for(int i=linkk[st];i;i=e[i].next){
     6         if(e[i].y!=father) dfs(e[i].y,st,depth+1);
     7     }
     8 }
     9 getanser(){//用倍增得出f数组 
    10     for(in i=1;i<=25;i++){
    11         for(int j=1;j<=n;j++){
    12             f[j][i]=f[f[j][i-1]][i-1];//f[j][i]由i往上跳到f[j-1][i]再往上跳2^(i-1)得到 
    13         }
    14     }
    15 }
    16 int gerlca(int xx,int yy){//求xx和yy的lca
    17     if(xx==yy) return xx;//如果xx和yy相同那么就返回xx 
    18     if(depth[xx]<depth[yy]) swap(xx,yy);//为了统一下面的代码,如果xx的深度小于yy的深度,就交换xx和yy 
    19     for(int i=25;i>=0;i--){
    20         if(dep[xx]-(2<<i)>=dep[yy]) xx=fa[xx][i];//如果xx的深度往上跳1^i还比yy的深度大并且没有跳出范围的话,就跳 
    21     } 
    22     //跳完后xx和yy的深度相等 
    23     if(xx==yy) return xx;//如果这时候xx和yy相等就返回xx 
    24     for(int i=25;i>=0;i--){
    25         if(fa[xx][i]!=fa[yy][i]&&fa[xx][i]!=0){//如果不相等并且没有跳出范围的话,xx和yy同时往上跳1^i 
    26             xx=fa[xx][i];yy=fa[yy][i];
    27         } 
    28     }
    29     return fa[xx][0];//返回xx的父亲 
    30 }
    View Code

    看完代码,有几个需要注意的地方

    1.树根的父亲也就是fa[root][0]=0;

    2.为什么求lca的过程是合法的?

    首先深度不同的xx和yy肯定是不相同的,我们先把xx和yy的深度统一到小的那个上

    那么这时候xx和yy离最近公共祖先的距离就是相同的,所以一起往上跳

    而且最后他们不可能跳到一块去,会离公共祖先差1(原因:我们知道一个数n可以有若干个不重复的2自然数次幂构成。。。。)

    这就是为什么要返回xx的父亲的原因了

  • 相关阅读:
    SQLite学习手册(开篇)
    SQLite学习手册(索引和数据分析/清理)
    SQLite学习手册(在线备份)
    SQLite学习手册(数据类型)
    SQLite学习手册(表达式)
    SQLite学习手册(C/C++接口简介)
    SQLite学习手册(命令行工具)
    (转)Graphical Execution Plans for Simple SQL Queries
    诡异的Request
    今天用windows live writer 2009写博客了
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/7799175.html
Copyright © 2011-2022 走看看