HLG 1373 Leyni, LOLI and Leaders【括号定理】

Description

Professor Leyni likes to play with LOLIs and he has a lot of LOLIs to manage.

For easy management, Leyni numbered them from 1 to n, then arranged some leading relationships between them, such as, x leads y.

This relationship is transitive (i.e. if x is the leader of y, y leads z, and then x will lead z.).Leyni ensures that the arrangements will not conflict (i.e. x will not lead x by itself, x will not lead y if y leads x).

Since there are too many LOLIs, it troubles him whenever he would like to know the relationship between some pairs of LOLIs, please help him!

Input

There are multiple test cases. The first line of input is an integer T indicating the number of test cases. Then T test cases follow.

For each test case:

Line 1. This line contains a single integer n (2 ≤ n ≤ 105) indicating the number of LOLIs.

Line 2. This line contains n integers l1l2ln (0 ≤ lin) separated by a single space. It means the leader of i is li. It means i is headed by Leyni when li = 0.

Line 3. This line contains an integer Q (1 ≤ Q ≤ 105) indicating the number of queries about the relationship of some pairs of LOLIs.

Line 4..3 + Q. Each line contains two integer x and y (1 ≤ xyn)indicating two different LOLIs of each query.

Output

For each test case:

Line 1..Q. Corresponding to each query, an answer per line. Output "x>y" if x leads y, output "x<y" if y leads x, otherwise output "x<>y" instead.

Sample Input

1

10

2 3 6 3 1 0 3 6 6 6

5

10 5

9 10

3 5

8 2

5 1

Sample Output

10<>5

9<>10

3>5

8<>2

5<1

分析:

根据题意,判断一颗树中,某个点是否是另一个点的后裔。根据递归函数的入栈出栈时间戳特点(即子结点的入栈时间戳要晚于自己,而且子节点的出栈时间戳要早于自己)或者括号定理在O(N)内预处理一遍图,即可在O(1)时间完成每次查询。

d[x]表示深度优先搜索中x的访问时间戳

f[x]表示深度优先搜索中x的结束访问时间戳

如果d[u] < d[v] < f[v] < f[u],那么vu的后裔。

 

总结: 继续刷题吧。。

View Code
#include<stdio.h>
#include<string.h>
int f[100005],d[100005];
struct node
{
    int to,next;
}q[1000000];
int head[100005];
int tot;
int ti;
void add(int s,int u)
{
    q[tot].to=u;
    q[tot].next=head[s];
    head[s]=tot++;
}
void dfs(int r)
{
    int k,i,flag=1;
    d[r]=ti++;
    for(i=head[r];i;i=q[i].next)
    {
        flag=0;
        k=q[i].to;
        dfs(k);
    }
    f[r]=ti++;
}
int main()
{
    int t,n,i,p,root,a,b,Q;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        memset(head,0,sizeof(head));
        tot=1;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&p);
            if(p==0)
                root=i;
            else
                add(p,i);
        }
        memset(d,0,sizeof(d));
        memset(f,0,sizeof(f));
        ti=0;
        dfs(root);
        scanf("%d",&Q);
        while(Q--)
        {
            scanf("%d%d",&a,&b);
            if(d[a]<d[b]&&d[b]<=f[b]&&f[b]<=f[a])
                printf("%d>%d\n",a,b);
            else if(d[b]<d[a]&&d[a]<=f[a]&&f[a]<=f[b])
                printf("%d<%d\n",a,b);
            else printf("%d<>%d\n",a,b);
        }
    }
    return 0;
}

 

 

转载于:https://www.cnblogs.com/dream-wind/archive/2012/04/23/2466269.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值