zoukankan      html  css  js  c++  java
  • hzwer 模拟题 祖孙询问

              祖孙询问

    题目描述

    已知一棵n个节点的有根树。有m个询问。每个询问给出了一对节点的编号x和y,询问x与y的祖孙关系。

    输入输出格式

    输入格式:

    输入第一行包括一个整数n表示节点个数。 接下来n行每行一对整数对a和b表示a和b之间有连边。如果b是-1,那么a就是树的根。 第n+2行是一个整数m表示询问个数。 接下来m行,每行两个正整数x和y。

    输出格式:

    对于每一个询问,如果x是y的祖先,输出1;如果y是x的祖先,输出2;否则输出0。

    输入输出样例

    输入样例#1: 复制
    10
    234 -1
    12 234
    13 234
    14 234
    15 234
    16 234
    17 234
    18 234
    19 234
    233 19
    5
    234 233
    233 12
    233 13
    233 15
    233 19
    输出样例#1: 复制
    1
    0
    0
    0
    2

    说明

    对于30%的数据,n, m ≤ 1000。

    对于100%的数据,n, m ≤ 40000,每个节点的编号都不超过40000。

    思路:求出两点的LCA后,若其中有一个点为LCA,则这个点为另一个点的祖先,输出 1 或 2,反之,输出 0

    #include<cstdio>
    #include<algorithm>
    
    const int N=40001;
    int n,m,tot,root,fa[N],ans[N],head[N],_head[N];
    struct Edge{
        int v,nxt;
    }edge[N<<1];
    struct EDge{
        int x,v,nxt,id;
    }_edge[N<<1];
    
    inline int read()
    {
        int n=0,w=1;register char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
        while(c>='0'&&c<='9')n=n*10+c-'0',c=getchar();
        return n*w;
    }
    
    int find(int x)
    {return fa[x]==x?fa[x]:fa[x]=find(fa[x]);}
    
    inline void add(int u,int v)
    {edge[++tot]=(Edge){v,head[u]};head[u]=tot;}
    inline void _add(int x,int u,int v,int i)
    {_edge[++tot]=(EDge){x,v,_head[u],i};_head[u]=tot;}
    
    bool vis[N];
    void dfs(int now)
    {
        vis[now]=true;
        for(int v,i=head[now];i;i=edge[i].nxt)
            if(!vis[v=edge[i].v])
                dfs(v),fa[v]=now;
        for(int x,i=_head[now];i;i=_edge[i].nxt)
            if(vis[_edge[i].v])
            {
                x=find(_edge[i].v);
                if(x==now)
                    ans[_edge[i].id]=(now==_edge[i].x?1:2);
            }
    }
    
    int main()
    {
        n=read();
        for(int i=1;i<=N;++i)
            fa[i]=i;
        for(int u,v,i=1;i<=n;++i)
        {
            u=read(),v=read();
            if(v==-1)
                root=u;
            else    add(u,v),add(v,u);
        }
        tot=0;m=read();
        for(int x,y,i=1;i<=m;++i)
        {
            x=read(),y=read();
            _add(x,x,y,i),_add(x,y,x,i);
        }
        dfs(root);
        for(int i=1;i<=m;++i)
            printf("%d
    ",ans[i]);
        return 0;
    }
  • 相关阅读:
    反射、枚举
    WebService、Http请求、Socket请求
    RPC和REST的区别
    命名分组
    golang isPowerOfTwo判断是否是2的幂
    golang 判断平台是32位还是64位
    vue的permission.js详解
    windows 下完全卸载oracle 11的详细过程
    freemarker导出word
    freemarker详细教程从入门到精通(三)模板入门与指令
  • 原文地址:https://www.cnblogs.com/v-vip/p/9805861.html
Copyright © 2011-2022 走看看