题意:给定一棵以1为根的n个节点的树,多个询问,每次询问给出一个集合,集合内的点表示为不重要的点(不在集合内的点就是重要的点),求给定这个集合后有多少点能进入另一个集合,点x进入另一个集合的要求:1:重要的点。2:有两个重要的点的最近公共祖先为x。

分析:其实对于每一个询问我们只要判断哪些不重要的点是能进入集合的,那么对于一个不重要的点x,怎样才能进入集合呢?我们先dfs对于所有的点求出fa[x]和son[x]。当询问是,我们先初始确定每个不重要的点的son'[x],如果一个点要进入集合那么显然要求son'[x]>=2,这样才会有两个重要的点的最近公共祖先是x。那么对于一个点x的son'又会受什么影响呢?当一个点y满足son'[y]==0&&y是不重要的点那么son'[fa[y]]--。这样我们就能维护我们需要的信息了。O(mlogm)

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
 1 #include<map>  2 #include<set>  3 #include<cmath>  4 #include<queue>  5 #include<bitset>  6 #include<math.h>  7 #include<vector>  8 #include<string>  9 #include<stdio.h> 10 #include<cstring> 11 #include<iostream> 12 #include<algorithm> 13 #pragma comment(linker, "/STACK:102400000,102400000") 14 using namespace std; 15 const int N=100010; 16 const int M=50010; 17 const int mod=1000000007; 18 const int MOD1=1000000007; 19 const int MOD2=1000000009; 20 const double EPS=0.00000001; 21 typedef long long ll; 22 const ll MOD=1000000007; 23 const int INF=1000000010; 24 const ll MAX=1ll<<55; 25 const double eps=1e-5; 26 const double inf=~0u>>1; 27 const double pi=acos(-1.0); 28 typedef double db; 29 typedef unsigned int uint; 30 typedef unsigned long long ull; 31 int tot,u[N],v[2*N],pre[2*N]; 32 int fa[N],son[N],dep[N]; 33 int d[N],so[N]; 34 void add(int a,int b) { 35 v[tot]=b;pre[tot]=u[a];u[a]=tot++; 36 v[tot]=a;pre[tot]=u[b];u[b]=tot++; 37 } 38 void dfs(int a,int b) { 39 fa[a]=b;dep[a]=dep[b]+1;son[a]=0; 40 for (int i=u[a];~i;i=pre[i]) 41 if (v[i]!=b) dfs(v[i],a),son[a]++; 42 } 43 int cmd(int a,int b) { 44 return dep[a]>dep[b]; 45 } 46 int main() 47 { 48 int a,b,i,n,m,q,ca,T,ans; 49 scanf("%d", &T); 50 for (ca=1;ca<=T;ca++) { 51 scanf("%d%d", &n, &q); 52 for (tot=0,i=1;i<=n;i++) u[i]=-1; 53 for (i=1;i<n;i++) scanf("%d%d", &a, &b),add(a,b); 54 dfs(1,0); 55 printf("Case #%d:\n", ca); 56 while (q--) { 57 scanf("%d", &m);ans=n-m; 58 for (i=1;i<=m;i++) scanf("%d", &d[i]); 59 sort(d+1,d+m+1,cmd); 60 for (i=1;i<=m;i++) so[d[i]]=son[d[i]]; 61 for (i=1;i<=m;i++) 62 if (so[d[i]]>=2) ans++; 63 else if (so[d[i]]==0) so[fa[d[i]]]--; 64 printf("%d\n", ans); 65  } 66  } 67 return 0; 68 }

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄