[Codeforces1006E] Military Problem(DFS)

链接:http://codeforces.com/contest/1006/problem/E

给一棵n个节点的树和q次询问,每次询问两个数uk,表示第u个节点的第k个前序遍历的结果是谁。

这么水的题竟然放在了E,可能这就是div 3吧…

dfs一遍,维护出每个节点i的前序遍历的次序reti,以及该节点的子树中共计多少个节点szi,可以利用reti维护出第j号遍历的节点是idi。当我们要求的某节点开始往后数k个数不存在时,输出-1;否则我们的答案就是ret[id[u]+k1]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <bits/stdc++.h>
using namespace std;

const int maxn = 200100;
int n, q, tot;
vector<int> G[maxn];
int ret[maxn], sz[maxn], id[maxn];

int dfs(int u, int p) {
ret[++tot] = u;
int son = 1;
for(int i = 0; i < G[u].size(); i++) {
int &v = G[u][i];
if(v == p) continue;
son += dfs(v, u);
}
return sz[u] = son;
}

signed main() {
// freopen("in", "r", stdin);
int u, k;
while(~scanf("%d%d",&n,&q)) {
tot = 0;
memset(ret, -1, sizeof(ret));
memset(sz, 0, sizeof(sz));
for(int i = 1; i <= n; i++) G[i].clear();
for(int i = 2; i <= n; i++) {
scanf("%d",&u);
G[i].push_back(u);
G[u].push_back(i);
}
sz[1] = dfs(1, -1);
for(int i = 1; i <= n; i++) id[ret[i]] = i;
while(q--) {
scanf("%d%d",&u,&k);
if(k - 1 >= sz[u]) printf("-1\n");
else printf("%d\n", ret[id[u]+k-1]);
}
}
return 0;
}
Code 401: 未经授权的操作,请检查你的AppId和AppKey.
Powered By Valine
v1.5.2