dfs中引用l r这两个数组可以来说明该节点所在的子树的最小和最大编号
很明显 本身就是最小的编号 最大的编号就是访问完所有的子节点之后的编号
//MADE BY Y_is_sunshine;
//#include <bits/stdc++.h>
//#include <memory.h>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <cstdio>
#include <vector>
#include <string>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define pb push_back
#define INF 0x3f3f3f3f
#define MAXN (int) 2e5 + 7
typedef long long ll;
const ll mod = 998244353;
const double PI = acos(-1);
using namespace std;
int N, M, K;
vector<int> g[MAXN];
int f[MAXN];
int l[MAXN];
int r[MAXN];
int cnt;
int cnt_2;
void dfs(int u, int fa) {
l[u] = ++cnt_2;
for (auto it : g[u]) {
int v = it;
if (v == fa)
continue;
f[v] = u;
dfs(v, u);
}
r[u] = ++cnt;
}
int cmp(int a, int b){
return l[a] < l[b];
}
int main(void)
{
#ifdef Sunshine
freopen("data.txt", "r", stdin);
#endif
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int T;
cin >> N >> T;
for (int i = 1; i < N; i++) {
int u, v;
cin >> u >> v;
g[u].pb(v);
g[v].pb(u);
}
dfs(1, -1);
f[1] = 1;
while (T--) {
cin >> M;
vector<int> v1;
while (M--) {
int a;
cin >> a;
v1.pb(f[a]);
}
sort(v1.begin(), v1.end(), cmp);
int _min, _max;
_min = 0;
_max = N;
bool ok = true;
for (int i = 0; i < v1.size(); i++) {
if (_min <= l[v1[i]] && _max >= r[v1[i]]) {
_min = l[v1[i]];
_max = r[v1[i]];
}
else ok = false;
}
if (ok)
cout << "YES\n";
else
cout << "NO\n";
}
#ifdef Sunshine
freopen("CON", "r", stdin);
system("pause");
#endif
return 0;
}