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; }
没有人不辛苦,只有人不喊疼