Codeforces Round 629 (Div. 3) E

76 阅读3分钟

You are given a rooted tree consisting of n vertices numbered from 1 to n. The root of the tree is a vertex number 1.

A tree is a connected undirected graph with n−1 edges.

You are given m queries. The i-th query consists of the set of ki distinct vertices vi[1],vi[2],…,vi[ki]. Your task is to say if there is a path from the root to some vertex u such that each of the given k vertices is either belongs to this path or has the distance 1 to some vertex of this path.

Input

The first line of the input contains two integers n and m (2≤n≤2⋅105, 1≤m≤2⋅105) — the number of vertices in the tree and the number of queries.

Each of the next n−1 lines describes an edge of the tree. Edge i is denoted by two integers ui and vi, the labels of vertices it connects (1≤ui,vi≤n,ui≠vi).

It is guaranteed that the given edges form a tree.

The next m lines describe queries. The i-th line describes the i-th query and starts with the integer ki (1≤ki≤n1) — the number of vertices in the current query. Then ki integers follow: vi[1],vi[2],…,vi[ki] (1≤vi[j]≤n), where vi[j] is the j-th vertex of the i-th query.

It is guaranteed that all vertices in a single query are distinct.

It is guaranteed that the sum of ki does not exceed 2⋅105 (∑i=1mki≤2⋅105).

Output

For each query, print the answer — "YES", if there is a path from the root to some vertex u such that each of the given k vertices is either belongs to this path or has the distance 1 to some vertex of this path and "NO" otherwise.

Example

input

Copy

10 6
1 2
1 3
1 4
2 5
2 6
3 7
7 8
7 9
9 10
4 3 8 9 10
3 2 4 6
3 2 1 5
3 4 8 2
2 6 10
3 5 4 7

output

Copy

YES
YES
YES
YES
NO
NO

Note

The picture corresponding to the example:

Consider the queries.

The first query is [3,8,9,10]. The answer is "YES" as you can choose the path from the root 1 to the vertex u=10. Then vertices [3,9,10] belong to the path from 11 to 1010 and the vertex 8 has distance 1 to the vertex 7 which also belongs to this path.

The second query is [2,4,6]. The answer is "YES" as you can choose the path to the vertex u=2. Then the vertex 4 has distance 1 to the vertex 1 which belongs to this path and the vertex 6 has distance 1 to the vertex 2 which belongs to this path.

The third query is [2,1,5]. The answer is "YES" as you can choose the path to the vertex u=5 and all vertices of the query belong to this path.

The fourth query is [4,8,2]. The answer is "YES" as you can choose the path to the vertex u=9 so vertices 2 and 4 both have distance 1 to the vertex 1 which belongs to this path and the vertex 88 has distance 1 to the vertex 7 which belongs to this path.

The fifth and the sixth queries both have answer "NO" because you cannot choose suitable vertex u.

题意:

就是给你一棵树然后m次询问,问这些节点是不是在同一路径或者不在同一路径他们具有相同的父亲节点

思路:

dfs序找出一个点的两个范围,左右,然后他的子节点的左右一定在这个范围,然后按深度排序遍历一遍是否满足即可

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define YES puts("YES");
#define NO puts("NO");
#define Yes puts("Yes");
#define No puts("No");
const int N = 1e6 + 10;
int n,m;
vector<int>edge[N];
int tot = 0;
struct NOW{
    int l;
    int r;
}seg[N];
int dep[N],pre[N];
void dfs(int u,int f){
    seg[u].l = ++tot;
    dep[u] = dep[f] + 1;
    pre[u] = f;
    for(auto v:edge[u]){
        if(v == f)
        continue;
        dfs(v,u);
    }
    seg[u].r = tot;
}
struct node{
    int s;
    int w;
}a[N];
bool cmp(node ll,node rr)
{
    return ll.s < rr.s;
}
bool check1(int xx,int yy)
{
    if(seg[xx].l <= seg[yy].l&&seg[yy].l<=seg[xx].r)
    {
        //cout << "w" << '\n';
        return true;
    }
    return false;
}
bool check(int k)
{
    for(int i = 1;i < k;i++)
    {
        if(check1(a[i].w,a[i+1].w))
            continue;
        if(check1(pre[a[i].w],a[i+1].w))
            continue;
        //cout << "y"<<'\n';
        return false;
    }
    return true;
}

void solve()
{
    cin >> n >> m;
    for(int i = 1;i < n;i ++)
    {
        int x,y;
        cin >> x >> y;
        edge[x].push_back(y);
        edge[y].push_back(x);
    }
    dfs(1,0);
    for(int i = 1;i <= m;i ++)
    {
        int k;
        cin >> k;
        for(int i = 1;i <= k;i ++)
        {
            int x;
            cin >> x;
            a[i] = {dep[x],x};
        }
        sort(a+1,a+k+1,cmp);
        if(check(k))
        {
            YES;
        }
        else
        NO;
    }
}
signed main()
{
    int tt = 1;
    //sc(tt);
    while(tt--)
    {
    solve();
    }
}