题目 | Subtree K-th Max
Denso Create Programming Contest 2022(AtCoder Beginner Contest 239)
E - Subtree K-th Max
https://atcoder.jp/contests/abc239/tasks/abc239_e
Time Limit: 2 sec / Memory Limit: 1024 MB
Score :
Problem Statement
We have a rooted tree with
The
Vertex
You are given
- Question: among the integers written on the vertices in the subtree rooted at Vertex
, find the -th largest value.
Constraints
- The given graph is a tree.
- The subtree rooted at Vertex
has or more vertices. - All values in input are integers.
Input
Input is given from Standard Input in the following format:
Output
Print
Sample Input 1
5 2
1 2 3 4 5
1 4
2 1
2 5
3 2
1 2
2 1
Sample Output 1
4
5
The tree given in this input is shown below.
For the
For the
Sample Input 2
6 2
10 10 10 9 8 8
1 4
2 1
2 5
3 2
6 4
1 4
2 2
Sample Output 2
9
10
Sample Input 3
4 4
1 10 100 1000
1 2
2 3
3 4
1 4
2 3
3 2
4 1
Sample Output 3
1
10
100
1000
我的笔记
核心思路就是预计算出每一个节点的前 vector<int> max_20_value[node]
里,最后直接输出对应第 max_20_value[N][max_20_value[N].size() - Q]
。
具体做法是先建树,储存每个节点的子节点和父节点。
然后用 DFS,每一个节点的操作:先将它的所有子节点的 max_20_value[subnode]
的值全部添加到自身的 max_20_value[node]
内,然后排序,如果值的数量
因为 DFS 每一层都需要用到下一层的结果,所以得先递归到底然后再进行操作。对应到代码就是每一层先 DFS,再进行其他操作。
代码
#include <bits/stdc++.h>
#define SIZE 100010
using namespace std;
vector<int> max_20_value[SIZE];
vector<int> link[SIZE];
int father[SIZE] = {0, 1};
vector<int> son[SIZE];
void creat_tree(int x)
{
for (auto i : link[x])
{
if (father[i])
continue;
father[i] = x;
son[x].push_back(i);
creat_tree(i);
}
}
void calc_max_20_value(int x)
{
for (auto i : son[x])
{
calc_max_20_value(i);
for (auto j : max_20_value[i])
{
max_20_value[x].push_back(j);
}
}
sort(max_20_value[x].begin(), max_20_value[x].end());
while (max_20_value[x].size() > 20)
{
max_20_value[x].erase(max_20_value[x].begin());
}
}
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
int N, Q;
cin >> N >> Q;
for (int i = 1; i <= N; i++)
{
int X;
cin >> X;
max_20_value[i].push_back(X);
}
for (int i = 1; i < N; i++)
{
int A, B;
cin >> A >> B;
link[A].push_back(B);
link[B].push_back(A);
}
creat_tree(1);
calc_max_20_value(1);
for (int i = 1; i <= Q; i++)
{
int N, Q;
cin >> N >> Q;
cout << max_20_value[N][max_20_value[N].size() - Q] << endl;
}
return 0;
}
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi