zoukankan      html  css  js  c++  java
  • 约会 倍增lca

    题意:一棵树,给两个点,求树上有多少点到他俩距离相等

    倍增lca,分好多情况讨论。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #define N 100500
    using namespace std;
    int e=1,head[N];
    struct edge{
        int u,v,next;
    }ed[2*N];
    void add(int u,int v){
        ed[e].u=u;ed[e].v=v;
        ed[e].next=head[u];
        head[u]=e++;
    }
    int n,m;
    int dep[N],fa[N][22],size[N];
    void dfs(int x){
        size[x]=1;
        for(int i=1;(1<<i)<=dep[x];i++)
            fa[x][i]=fa[fa[x][i-1]][i-1];
        for(int i=head[x];i;i=ed[i].next){
            int v=ed[i].v;
            if(v==fa[x][0])continue;
            fa[v][0]=x;dep[v]=dep[x]+1;
            dfs(v); 
            size[x]+=size[v];
        }
    }
    int getlca(int x,int y){
        if(dep[x]<dep[y])swap(x,y);
        for(int i=20;~i;i--)
            if(dep[fa[x][i]]>=dep[y]){
                x=fa[x][i];
            }
        if(x==y) return x;
        for(int i=20;~i;i--)
            if(fa[x][i]!=fa[y][i]){
                x=fa[x][i];y=fa[y][i];
            }
        return fa[x][0];
    }
    int find(int x,int y){
        int d=dep[x]-y;
        for(int i=20;~i;i--)
            if(dep[fa[x][i]]>=d)
                x=fa[x][i];
        return x;
    }
    int main(){
        scanf("%d",&n);int u,v;
        for(int i=1;i<n;i++){
            scanf("%d%d",&u,&v);
            add(u,v);add(v,u);
        }
        dep[1]=1;fa[1][0]=0;
        dfs(1);
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&u,&v);
            if(u==v){printf("%d
    ",n);continue;}
            if(dep[u]>dep[v])swap(u,v);
            int lca=getlca(v,u),mid,len;
            if(lca==u){
                len=dep[v]-dep[u];
                if(len%2==1){printf("%d
    ",0);continue;}
                else{
                    mid=find(v,len/2);
                    printf("%d
    ",size[mid]-size[find(v,dep[v]-dep[mid]-1)]);
                    continue;
                }
            }
            len=dep[u]+dep[v]-2*dep[lca];
            if(len%2==1){printf("%d
    ",0);continue;}
            else{
                mid=find(v,len/2);
                if(mid==lca){
                    printf("%d
    ",n-size[find(u,dep[u]-dep[lca]-1)]-size[find(v,dep[v]-dep[lca]-1)]);
                    continue;
                }
                else{
                    printf("%d
    ",size[mid]-size[find(v,dep[v]-dep[mid]-1)]);
                    continue;
                }
            }
        }
        return 0;
    }


  • 相关阅读:
    zabbix源码安装
    利用Linux系统生成随机密码的8种方法
    Java 内存溢出(java.lang.OutOfMemoryError)的常见情况和处理方式总结
    Jenkins的参数化构建
    Jenkins中maven的作用--构建项目(三)
    Beans(dp,两次dp)
    Piggy-Bank(完全背包)
    Super Jumping! Jumping! Jumping!(dp)
    01串(dp)
    钱币兑换问题(完全背包)
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/7746691.html
Copyright © 2011-2022 走看看