• 祖孙询问


    题目描述 Description###

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

    输入描述 Input Description###

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

    输出描述 Output Description###

    对于每一个询问,输出1:如果(x)(y) 的祖先,输出2:如果(y)(x) 的祖先,否则输出(0)

    样例输入 Sample Input###

    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
    

    样例输出 Sample Output###

    1
    0
    0
    0
    2
    

    数据范围及提示 Data Size & Hint###

    数据范围:对于30%的数据,(n,m≤1000) ,对于100%的.据,(n,m≤40000) ,每个节点的编号都不超过(40000)

    之前的一些废话###

    题解###

    对于一棵树求一下(dfs) 序,根据(dfs) 的顺序,每一个点的子孙都属于(dfs) 序中的一个区间,所以在(dfs) 时维护即可。

    代码###

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    typedef long long LL;
    #define mem(a,b) memset(a,b,sizeof(a))
    typedef pair<int,int> PII;
    #define X first
    #define Y second
    #define mp make_pair
    inline int read()
    {
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    	return x*f;
    }
    const int maxn=40010;
    int n,first[maxn],ce=-1,q,a,b,rt,l[maxn],r[maxn],dfs_clock,m;
    struct Edge
    {
    	int u,v,next;
    	Edge() {}
    	Edge(int _1,int _2,int _3):u(_1),v(_2),next(_3) {}
    }e[maxn<<1];
    void addEdge(int a,int b)
    {
    	e[++ce]=Edge(a,b,first[a]);first[a]=ce;
    	e[++ce]=Edge(b,a,first[b]);first[b]=ce;
    }
    void dfs(int now,int fa)
    {
    	l[now]=++dfs_clock;
    	for(int i=first[now];i!=-1;i=e[i].next)
    		if(e[i].v!=fa)dfs(e[i].v,now);
    	r[now]=dfs_clock;
    }
    int main()
    {
    	mem(first,-1);
    	n=read();
    	for(int i=1;i<=n;i++)
    	{
    		a=read(),b=read();
    		if(b!=-1)addEdge(a,b);
    		else rt=a;
    	}
    	dfs(rt,-1);
    	m=read();
    	while(m--)
    	{
    		a=read();b=read();
    		if(l[b]<=r[a] && l[b]>l[a])printf("1
    ");
    		else if(l[a]<=r[b] && l[a]>l[b])printf("2
    ");
    		else printf("0
    ");
    	}
    	return 0;
    }
    

    总结###

  • 相关阅读:
    嵌入式:指针的指针、链表、UCOS 的 OSMemCreate 。
    嵌入式&iOS:回调函数(C)与block(OC)传 参/函数 对比
    嵌入式&iOS:回调函数(C)与block(OC)回调对比
    iOS:以前笔记,未整理版。太多了,先放着吧。。。。。。。
    嵌入式:小技巧(慢慢回忆更新)(16.12.17更)
    嵌入式:J-link刷固件(坑)
    iOS:GCD组
    Android Studio教程07-Fragment的使用
    Android Studio教程06-布局,监听器以及基本控件
    Android Studio教程05-Parcelables和Bundles.md
  • 原文地址:https://www.cnblogs.com/FYH-SSGSS/p/7811066.html
Copyright © 2020-2023  润新知