(beginer) DFS LA3486 Cells

1357 - Cells

Time limit: 3.000 seconds

Scientists are conducting research on the behavior of a newly discovered Agamic Cellular Microbe. This special kind of microbe is capable of massively reproducing by itself in a short time. The lifetime of an ACM consists of three phases:

  1. The infancy phase, which starts from its birth and lasts for approximately several seconds;
  2. The multiplication phase, in which one ACM can procreate up to 100 offspring in only several milliseconds;
  3. The mature phase, in which it remains inactive for the rest of its life.

At the beginning of the experiment, a newborn, single cell of ACM, is put into a suitable circumstance for its production. This cell, numbered as 0, starts to multiply and its descendants are numbered, starting from 1, according to their positions in the family hierarchy. During the experiment special equipment is used to record the numbers of the offspring generated by each of the ACM's. The experiment is stopped after a certain time period.

\epsfbox{p3486.eps}

The family tree of ACM's in the first case of sample input

Your task is to help the scientists to determine whether one ACM is an ancestor of another.

Input 

Standard input will contain multiple test cases. The first line of the input is a single integer T (1$ \le$T$ \le$10) which is the number of test cases. T test cases follow, each preceded by a single blank line.

Each test case starts with a single integer N (1$ \le$N$ \le$300, 000) which is the number of ACM's that have their descendants recorded. The following N integers (not necessarily on a same line), Ci (0$ \le$i < N, 0$ \le$Ci$ \le$100) , give the number of offspring of the i -th ACM. The next line contains an integer M (1$ \le$M$ \le$1, 000, 000) which is the number of queries. M lines follow, each contains two integers a and b , querying whether the a -th ACM is an ancestor of the b -th ACM.

The total number of ACM's may be greater than N , but would never exceed 20,000,000.

Output 

Results should be directed to standard output. Start each case with "Case # : " on a single line, where # is the case number starting from 1. Two consecutive cases should be separated by a single blank line. No blank line should be produced after the last test case.

For each query, print either ``Yes" or ``No" on a single line, which is the answer to the query.

Sample Input 

2

6
3 2 1 1 0 2
5
0 1
2 4
3 5
1 8
6 9

5
2 0 3 0 1
4
2 6
1 6
2 3
3 5

Sample Output 

Case 1:
Yes
No
No
Yes
No

Case 2:
Yes
No
Yes
No
 
题意:给出一颗树的结构,然后有m次的询问,问a是不是b的祖先。

思路:一开始先预处理一下,从0开始dfs,形成一个搜索树,记录搜索的顺序,用pre记录第一次遇到的时间,post记录回来的时间。最后如果pre[a] < pre[b] && post[a] > post[b] ,a就是b的祖先。

代码:
#include<iostream>
#include<cstring>
#include<string.h>
#include<cstdio>
#include<stack>
using namespace std;
const int maxn = 300000+10;
const int maxtot = 20000000+10;

int dfs_clock , N , M , a , b;
int C[maxn] , start[maxn];
int pre[maxtot] , post[maxtot];

void input()
{
int cnt = 1;
for (int i = 0 ; i < N ; ++i)
{
scanf("%d",C+i);
start[i] = cnt;
cnt += C[i];
}
}

void dfs(int x)
{
stack<int> S;
pre[x] = 0;
dfs_clock = 0;
S.push(x);
while (S.size())
{
x = S.top();
if (pre[x])
{
post[x] = ++dfs_clock;
S.pop();
continue;
}
pre[x] = ++dfs_clock;
for (int y = start[x] ; y < start[x]+C[x] ; ++y) 
{
if (y < N) { pre[y] = 0 ; S.push(y); }
else { pre[y] = ++dfs_clock; post[y] = ++dfs_clock; }
}
}
}

void solve()
{
scanf("%d",&M);
while (M--)
{
scanf("%d%d",&a,&b);
if (pre[a] < pre[b] && post[a] > post[b]) printf("Yes\n");
else printf("No\n");
}
}

int main()
{
//freopen("input.in","r",stdin);
int T; cin>>T;
for (int t = 1 ; t <= T ; ++t)
{
scanf("%d",&N);
input();
dfs(0);
printf("Case %d:\n",t);
solve();
if (t < T) cout << endl;
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值