#include<set>
#include<map>
#include<stack>
#include<ctime>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<climits>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
int read(){
bool f=0;int x=0;char c=getchar();
while(c<'0'||'9'<c){if(c=='-')f=1;c=getchar();}
while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
return !f?x:-x;
}
#define MAXN 500000
#define INF 1000000000000000ll
struct Edge{
int v,nxt;
}edge[2*MAXN+5];
int ecnt,head[MAXN+5];
vector<int> G[MAXN+5];
inline void Addedge(int u,int v){
edge[++ecnt]=(Edge){v,head[u]},head[u]=ecnt;
edge[++ecnt]=(Edge){u,head[v]},head[v]=ecnt;
return ;
}
inline void addedge(int u,int v){
G[u].push_back(v);
G[v].push_back(u);
//printf("%d %d\n",u,v);
return ;
}
int ncnt,fa[MAXN+5],dep[MAXN+5],siz[MAXN+5],Maxson[MAXN+5],dfn[MAXN+5],top[MAXN+5];
void DFS1(int u){
siz[u]=1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].v;
if(v==fa[u]) continue;
fa[v]=u,dep[v]=dep[u]+1;
DFS1(v),siz[u]+=siz[v];
if(siz[v]>siz[Maxson[u]])
Maxson[u]=v;
}
return ;
}
void DFS2(int u,int t){
dfn[u]=++ncnt,top[u]=t;
if(!Maxson[u]) return ;
DFS2(Maxson[u],t);
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].v;
if(v==fa[u]||v==Maxson[u]) continue;
DFS2(v,v);
}
return ;
}
int LCA(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
u=fa[top[u]];
}
if(dep[u]>dep[v]) swap(u,v);
return u;
}
int tp,S[MAXN+5];
void Insert(int u){
int Lca=LCA(u,S[tp]);
if(Lca!=S[tp]){
while(dfn[S[tp-1]]>=dfn[Lca]) addedge(S[tp],S[tp-1]),tp--;
if(Lca!=S[tp]) addedge(Lca,S[tp--]),S[++tp]=Lca;
}
if(S[tp]!=u) S[++tp]=u;
return ;
}
bool vis[MAXN+5];
int f[MAXN+5],cnt[MAXN+5];
void Dfs(int u,int pre){
LL sum=0;
f[u]=0,cnt[u]=0;
for(int i=0;i<int(G[u].size());i++){
int v=G[u][i];
if(v==pre) continue;
Dfs(v,u),f[u]+=f[v],sum+=cnt[v];
}
if(vis[u]) cnt[u]=1,f[u]+=sum;
else if(sum>1) cnt[u]=0,f[u]++;
else cnt[u]=sum;
G[u].clear();
return ;
}
/*
int dp(int u){
int ans=0,sum=0;
go(u)ans+=dp(v),sum+=b[v];
if(fg[u])b[u]=1,ans+=sum;
else if(sum>1)b[u]=0,++ans;
else b[u]=sum;return fi[u]=0,ans;
}
*/
int a[MAXN+5];
bool cmp(int a,int b){return dfn[a]<dfn[b];}
int main(){
int n=read();
for(int i=1;i<n;i++){
int u=read(),v=read();
Addedge(u,v);
}
DFS1(1),DFS2(1,1);
int m=read();
for(int t=1;t<=m;t++){
int k=read();
for(int i=1;i<=k;i++)
a[i]=read(),vis[a[i]]=1;
for(int i=1;i<=k;i++)
if(vis[fa[a[i]]]){
puts("-1");
goto Break;
}
sort(a+1,a+k+1,cmp);
tp=1,S[tp]=1;
for(int i=1;i<=k;i++)
Insert(a[i]);
while(tp>1)
addedge(S[tp],S[tp-1]),tp--;
Dfs(1,0),printf("%d\n",f[1]);
Break:;
for(int i=1;i<=k;i++)
vis[a[i]]=0;
}
return 0;
}
虚树
最新推荐文章于 2022-05-27 19:20:22 发布