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;
    }


  • 相关阅读:
    JUnit-4.11使用报java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing错误
    生成验证码图片
    九九乘法表
    Java注解之Retention、Documented、Target、Inherited介绍
    【ztree】zTree节点增删改&ztree对树节点进行检索
    一次性搞清楚equals和hashCode
    HashMap实现原理分析
    DDL、DML和DCL的区别与理解
    MySQL的@与@@区别
    springboot整合mybatis(SSM开发环境搭建)&Springboot项目热部署
  • 原文地址:https://www.cnblogs.com/Ren-Ivan/p/7746691.html
Copyright © 2011-2022 走看看