zoukankan      html  css  js  c++  java
  • LCA 约会

        

    问题 C: 约会

    时间限制: 2 Sec  内存限制: 256 MB

    题目描述

    输入

    输出

    样例输入

    4
    1 2
    1 3
    2 4
    1
    2 3

    样例输出

    1

    提示

        一道不错的LCA的题。考试时想到正解,无奈打错LCA,超时了35分。。(一个新坑)

        这里是需要讨论的。

        一,如果求出的路径长为奇数,一定没有合法解。

        二,如果x==y,输出n。

        三,如果dep[x]==dep[y],设k=LCA(x,y),fx为x祖先,且dep[fx]==dep[k]+1,fy同理,

               则ans=n-size[fx]-size[fy],

        四,剩下就是正常情况了,设h为x,y距离,(设dep[x]>dep[y])k为x祖先,dep[k]==dep[x]-h/2.

               ans=size[k]-size[fx],fx为x祖先,dep[fx]==dep[k]+1.

        神犇ljy云:“我如果会LCA,我今天就AK了。”然并卵,我也是啊。。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define N 100000
    using namespace std;
    int read()
    {
        int sum=0,f=1;char x=getchar();
        while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
        while(x>='0'&&x<='9'){sum=(sum<<1)+(sum<<3)+x-'0';x=getchar();}
        return sum*f;
    }
    int n,m,adj[N+5],e;
    int f[N+5],dep[N+5],size[N+5],p[100005][20];
    struct road
    {
        int v,next;
    }lu[N*2+5];
    void add(int u,int v){lu[++e].v=v;lu[e].next=adj[u];adj[u]=e;}
    void dfs(int x,int deep)
    {
        size[x]=1;
        dep[x]=deep;
        for(int i=adj[x];i;i=lu[i].next)
        {
            int to=lu[i].v;
            if(to!=f[x])
            {
                f[to]=x;
                dfs(to,deep+1);
                size[x]+=size[to];
            }
        }
    }
    int get(int x,int y)
    {
        int i,j;
        if(dep[x]<dep[y])swap(x,y);
        for(i=0;(1<<i)<=dep[x];i++);
        i--;
        for(j=i;j>=0;j--)
            if(dep[x]-(1<<j)>=dep[y])
               x=p[x][j];
        if(x==y)return x;
        for(j=i;j>=0;j--)
           if(p[x][j]!=-1&&p[x][j]!=p[y][j])
           {
                x=p[x][j];
                y=p[y][j];
           }
        return f[x];  
    }
    void init()
    {
        for(int j=0;(1<<j)<=n;j++)
           for(int i=1;i<=n;i++)
              p[i][j]=-1;
        for(int i=1;i<=n;i++)p[i][0]=f[i];
        for(int j=1;(1<<j)<=n;j++)
           for(int i=1;i<=n;i++)
              if(p[i][j-1]!=-1)
                 p[i][j]=p[p[i][j-1]][j-1];
    }
    int zhao(int x,int h)
    {
        int i,j;
        for(i=0;(1<<i)<=dep[x];i++);
        i--;
        for(j=i;j>=0;j--)
           if(h-(1<<j)>=0)
           {
               h-=(1<<j);
               x=p[x][j];
           }
        return x;
    }
    int main()
    {
    //  freopen("date.in","r",stdin);
    //  freopen("date.out","w",stdout);
        n=read();
        int x,y;
        for(int i=1;i<n;i++)
        {
            x=read();y=read();
            add(x,y);add(y,x);
        }
        f[1]=0;
        dfs(1,1);
        init();
        m=read();
        int w,q;
        while(m--)
        {
            x=read();y=read();
            if(x==y){printf("%d
    ",n);continue;}
            int k=get(x,y);
            int h=dep[x]+dep[y]-2*dep[k];
            if(h%2){printf("0
    ");continue;}
            if(dep[x]==dep[y])
            {
                w=zhao(x,dep[x]-dep[k]-1);
                q=zhao(y,dep[y]-dep[k]-1);
                printf("%d
    ",n-size[w]-size[q]);
            }
            else
            {
                if(dep[x]>dep[y])swap(x,y);
                q=zhao(y,h/2),w=zhao(y,h/2-1);
                printf("%d
    ",size[q]-size[w]);
            }
        }
    }


  • 相关阅读:
    zBrow发布倒计时:对不起,让大家久等了
    《zBrow的资本论》
    zBrow智能浏览器
    zspt界面截图
    电商领域,唯一的“发明”级国家专利。
    zBrow界面截图截图
    zBrow多开界面截图
    网页滚动条样式
    关于margin参数解读
    JAVA的抽象类和抽象方法
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632705.html
Copyright © 2011-2022 走看看