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 l1,l2,… ln (0 ≤ li ≤ n) 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 ≤ x,y ≤ n),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],那么v是u的后裔。
总结: 继续刷题吧。。
#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; }