zoukankan      html  css  js  c++  java
  • [Graph]Doubling Algorithm

    Doubling Algorithm——倍增算法

    是一种可以优化时间复杂度的神奇的算法,可以用它来求LCA等等。

    基本思想:

    deep[i] 表示 i节点的深度, fa[i,j]表示 i 的 2^j (即2的j次方) 倍祖先,那么fa[i , 0]即为节点i 的父亲,

    然后就有一个递推式子:fa[i,j]= fa [ fa [i,j-1] , j-1] 。

    那么怎么求LCA呢,我们需先把深度更深的节点往上提直到深度和另一个节点一样,然后我们每次调2^i个节点(从最大可以

    跳的步数开始跳,若相反可能会导致找到的节点不是最近的),逐步缩小范围。

    Luogu 3379:

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #define maxn 1000005
    #define maxm 500005
    using namespace std;
    int n,p,gen;
    struct Tree{
        int next,to;
    }tree[maxn];
    int head[maxm]={0},f[maxm][21]={0},deep[maxm]={0},tot=0;
    void add(int x,int y){
        tot++;
        tree[tot].to=y;
        tree[tot].next=head[x];
        head[x]=tot;
    }
    void dfs(int u,int fa){
    deep[u]=deep[fa]+1;
        //printf("u:%d deep:%d
    ",u,deep[u]);
        f[u][0]=fa;
        int i;
        for( i=1;(1<<i)<=deep[u];i++){
            //if(f[u][i-1])
            f[u][i]=f[f[u][i-1]][i-1];
            //else break;
        }
        for(i=head[u];i!=-1;i=tree[i].next){
            if(tree[i].to!=fa)
            dfs(tree[i].to,u);
        }
    } 
    int lca(int x,int y){
        if(deep[x]<deep[y])
        swap(x,y);
        for(int i=20;i>=0;i--){
            if(deep[y]<=deep[x]-(1<<i))
            x=f[x][i];
        }
        if(x==y) return x;
        for(int i=20;i>=0;i--){
            if(f[x][i]!=f[y][i]){
                x=f[x][i];
                y=f[y][i];
            }
        }
    //    printf("x:%dy:%d
    ",x,y);
        return f[y][0];
    }
    int main()
    {
        memset(head,-1,sizeof(head));
        int x,y,i;
        scanf("%d%d%d",&n,&p,&gen);
        for(i=1;i<n;i++){
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs(gen,0);
        for(i=1;i<=p;i++){
            scanf("%d%d",&x,&y);
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }
    倍增求LCA

     

  • 相关阅读:
    Delphi接口的底层实现
    Delphi实现图像文本旋转特效完整代码
    delphi 原创应用工具箱
    用Delphi制作DLL
    Delphi在StatusBar上绘制ProgressBar
    Delphi之TDrawGrid绘制
    基于Delphi的接口编程入门
    Delphi中For In 语法应用实例
    w3c与微软(IE)事件注册区别 -Tom
    js 函数-Tom
  • 原文地址:https://www.cnblogs.com/Fish-/p/8228468.html
Copyright © 2011-2022 走看看