zoukankan      html  css  js  c++  java
  • LCA-最近公共祖先

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    struct zzz 
    {
        int t, nex;
    }e[500010 << 1]; int head[500010], tot;
    
    void add(int x, int y) 
    {
        e[++tot].t = y;
        e[tot].nex = head[x];
        head[x] = tot;
    }
    
    int depth[500001], fa[500001][22], lg[500001];
    
    void dfs(int now, int fath) 
    {
        fa[now][0] = fath; 
        depth[now] = depth[fath] + 1;
        
        for(int i = 1; i <= lg[depth[now]]; ++i)
            fa[now][i] = fa[fa[now][i-1]][i-1];
        
        for(int i = head[now]; i; i = e[i].nex)
            if(e[i].t != fath) 
            dfs(e[i].t, now);
            
    }
    
    int LCA(int x,int y)
    {
        
        if(depth[x]<depth[y])
        swap(x,y);
        
        while(depth[x]>depth[y])//tiao dao tong yi ceng
        x=fa[x][lg[depth[x]-depth[y]]-1];
        
        if(x==y)
        return x;
        
        for(int k=lg[depth[x]]-1;k>=0;--k)//qing gao dong zhe li
        {
            if(fa[x][k]!=fa[y][k])
            x=fa[x][k],y=fa[y][k];
        }
        
        return fa[x][0];
        
    }
    
    int main() 
    {
        int n, m, s; scanf("%d%d%d", &n, &m, &s);
        
        for(int i = 1; i <= n-1; ++i) 
        {
            int x, y; scanf("%d%d", &x, &y);
            add(x, y); add(y, x);
        }
        
        for(int i = 1; i <= n; ++i)
            lg[i] = lg[i-1] + (1 << lg[i-1] == i);
        dfs(s, 0);
        
        for(int i = 1; i <= m; ++i) 
        {
            int x, y; scanf("%d%d",&x, &y);
            printf("%d
    ", LCA(x, y));
        }
        return 0;
    }

     大体思路:首先建树,add来创建,dfs是深搜,主要是为了获取每个节点的深度(即到根节点的距离)。然后是整个代码最核心的思想,即将要查找的两个点进行比较,得出深度更深的那个点,随后,将得到的那个点一直往上跳(注意这里运用了倍增的思想以减小时间复杂度),直到跳到与另外一个点深度相同的一层上,最后将两个点同时向上跳,直到两个点跳到同一个点的下一层(如果直接调到第一个调到的同一个点,很有可能越过真正的公共祖先,因为你是倍增往上跳的),当跳到紧接着LCA点的下一层的时候,直接输出他们的父节点就好啦~

  • 相关阅读:
    SQL Server 连接字符串和身份验证 学习
    何時需要重启 OFBiz
    开源软件文档网址
    OFBIZ 10.04 开发环境搭建(ofbiz+mysql+eclipse)
    ofbiz 之minilang解析
    ofbiz之entity实体写法
    ofbiz多表外键关联查询
    ofbiz学习地址
    配置文件中的mime-mapping元素(ofbiz/framework/catalina/config/mime-type)(
    SQL连接 自我学习,跑完秒懂
  • 原文地址:https://www.cnblogs.com/dairuizhe/p/13246278.html
Copyright © 2011-2022 走看看