CF1328E Tree Queries (思维)

因为只有一条路,因此可以发现同一个深度的节点他们的父亲要相同

不同深度的节点,深度大的节点的父亲要在深度小的节点的父亲的子树当中

因此我们需要使用dfn就能查看是否在子树当中

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int N=4e5+10;
int h[N],ne[N],e[N],idx;
int p[N],dfn[N],times,sz[N],tmp[N],depth[N];
void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u,int fa){
    sz[u]=1;
    dfn[u]=++times;
    for(int i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa)
            continue;
        depth[j]=depth[u]+1;
        p[j]=u;
        dfs(j,u);
        sz[u]+=sz[j];
    }
}
bool cmp(int a,int b){
    return depth[a]<depth[b];
}
bool check(int a,int b){
    if(dfn[a]+sz[a]-1>=dfn[b]&&dfn[a]<=dfn[b])
        return true;
    return false;
}
int main(){
    ios::sync_with_stdio(false);
    memset(h,-1,sizeof h);
    int i;
    int n,m;
    cin>>n>>m;
    for(i=1;i<n;i++){
        int x,y;
        cin>>x>>y;
        add(x,y);
        add(y,x);
    }
    p[1]=1;
    depth[1]=1;
    dfs(1,-1);
    while(m--){
        int k;
        cin>>k;
        for(i=1;i<=k;i++){
            int x;
            cin>>x;
            tmp[i]=p[x];
        }
        sort(tmp+1,tmp+1+k,cmp);
        int flag=0;
        for(i=1;i<k;i++){
            if(!check(tmp[i],tmp[i+1])){
                flag=1;
                break;
            }
        }
        if(!flag){
            cout<<"YES"<<endl;
        }
        else{
            cout<<"NO"<<endl;
        }
    }
    return 0;
}
View Code

 

posted @ 2021-02-04 22:34  朝暮不思  阅读(94)  评论(0编辑  收藏  举报