• 倍增LCA


    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    
    const int M = 200005;
    struct Edge{
        int v, next;
    } edge[M << 1];
    int E; int head[M];
    void add_edge(int s, int v){
        edge[E].next = head[s];
        edge[E].v = v;
        head[s] = E ++;
    }
    int fa[M][23];
    
    int deep[M];
    int vis[M];
    int sum[M];
    
    void bfs(){
        queue<int> q;
        q.push(1);
        memset(vis, 0, sizeof(vis));
        memset(sum, 0, sizeof(sum));
        fa[1][0] = 1;
        deep[1] = 0;
        vis[1] = 1;
        sum[1] = 1;
        while(!q.empty()){
            int u = q.front(); q.pop();
            for(int j = 1; j <= 20; j ++) {
                fa[u][j] = fa[fa[u][j-1]][j-1];
            }
            for(int i = head[u]; i != -1; i = edge[i].next){
                int v = edge[i].v;
                if(vis[v]) continue;
                sum[v] = sum[u] + 1;
                vis[v] = 1;
    
                fa[v][0] = u;
                deep[v] = deep[u] + 1;
                q.push(v);
            }
        }
    }
    
    int lca(int a, int b){
        if(deep[a] > deep[b]) swap(a, b);
        int ta = a; int tb = b;
        int da = deep[a]; int db = deep[b];
        for(int i = 0, dd = db - da; dd; dd >>= 1, i ++){
            if(dd&1)
                tb = fa[tb][i];
        }
        if(tb == ta) return tb;
        for(int i = 20; i >= 0; i --){
            if(fa[ta][i] == fa[tb][i]) continue;
            ta = fa[ta][i];
            tb = fa[tb][i];
        }
        return fa[ta][0];
    
    }
    
    int main(){
        int n, m;
        scanf("%d%d", &n, &m);
        int a, b;
        memset(head, -1, sizeof(head));
        for(int i = 2; i <= n; i ++){
            scanf("%d", &a);
            add_edge(a, i);
            add_edge(i, a);
        }
        bfs();
        while(m --){
            scanf("%d%d", &a, &b);
            int lc = lca(a, b);
            if(deep[lc] == deep[a])
                printf("%d %d
    ", sum[lc], sum[b] - sum[lc]);
            else if(deep[lc] == deep[b]){
                printf("%d %d
    ", sum[a] - sum[lc], sum[lc]);
            }else {
                printf("%d %d
    ", sum[a], sum[b] - sum[lc]);
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    ASP.NET设置数据格式与String.Format使用总结(转)
    js 获取后台数据
    PowerDesigner设计的问题
    .Net设计模式
    js刷新
    UML使用问题
    Cookie揭秘
    数据库设计的十四个技巧
    jquery插件小试牛刀:文本框为空时默认文字显示,获得焦点后默认文字消失
    javascirpt 读写cookie
  • 原文地址:https://www.cnblogs.com/acmood/p/4537641.html
Copyright © 2020-2023  润新知