Files
python/GESP/Level6/20231202.cpp

82 lines
2.0 KiB
C++
Raw Normal View History

2025-08-30 18:35:01 +08:00
#include <bits/stdc++.h>
using namespace std;
const int N = 310; // 最多300个点
const int M = 310; // 最多299条边,因为它是树,300个点,其实是299条边
// 链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
int n;
set<int> a[N]; // 节点i可以管理的节点集合
// 树的深度优先搜索代码
void dfs(int u) { // 以u为根的子树的节点数量
// 遍历一下当前点的所有出边
for (int i = h[u]; i != -1; i = ne[i]) { // i是遍历 u的每条出边
int j = e[i]; // j是u的出边指向的节点
// 递归处理j
dfs(j);
// 针j中的所有孩子记录到u中去,注意:这个合并是要在dfs之后,因为dfs是先递归到最深,然后回溯
for (auto x : a[j])
a[u].insert(x);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("20231202_2.in", "r", stdin);
#endif
// 初始化链式前向星
memset(h, -1, sizeof h);
cin >> n;
// 构建单位的管理结构树
for (int i = 1; i < n; i++) { // 0号是老板
int f;
cin >> f;
add(f, i); // 表示i号员工的领导是f
a[f].insert(i); // f是i的领导
}
// 自己可以管理自己
for (int i = 0; i < n; i++)
a[i].insert(i);
// 递归一遍树
dfs(0);
int q;
cin >> q;
while (q--) {
int m;
cin >> m;
set<int> s; // 需要处理哪些人员集合
for (int i = 1; i <= m; i++) {
int x;
cin >> x;
s.insert(x);
}
// // 从n-1到0,找到第一个包含s的集合
for (int i = n - 1; i >= 0; i--) {
// 检查s中的每个元素是否都在a[i]中
bool flag = true;
for (auto x : s) {
if (a[i].find(x) == a[i].end()) {
flag = false;
break;
}
}
// 如果s中的所有元素都在a[i]中,则i是答案
if (flag) {
cout << i << endl;
break;
}
}
}
return 0;
}