首页 > 代码库 > hdu_5927_Auxiliary Set(xjb搞)
hdu_5927_Auxiliary Set(xjb搞)
题目链接:hdu_5927_Auxiliary Set
题意:
给一棵n个节点的树,最开始全部都是重点,现在有q个询问,每次给你一些轻点,并叫你输出整棵树的重点数量,
轻点可能会变为重点,如果这个轻点是两个重点的lca。
题解:
这里 我把有重点的子树叫重子树,一个重点都没有的子树叫轻子树。
一个轻点如果有两个重子树,那么这个轻点就会变为重点,可以画图试试。
然后我们就将轻点从树的最底层开始更新
x为这个点的子树个数,n为这个点的轻子树个数,
如果x-n=0,那么这个点的父亲节点的n就++
如果x-n<=1那么这个点就不能变会重点
最后统计一下轻点变回重点的个数
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5 const int N=1e5+7; 6 int ic=1,t,n,q; 7 int g[N],v[N*2],nxt[N*2],ed,dfs_idx,hsh[N]; 8 9 struct node10 {11 int in,pre,n,x,col,idx;12 bool operator < (const node &b)const{return in>b.in;}13 }nd[N],tmp[N];14 15 inline void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}16 17 void init()18 {19 memset(g,0,sizeof(g));20 ed=0,dfs_idx=0;21 }22 23 void dfs(int u=1,int pre=0)24 {25 nd[u].idx=u,nd[u].in=++dfs_idx,nd[u].pre=pre;26 nd[u].col=1,nd[u].n=0,nd[u].x=0;27 for(int i=g[u];i;i=nxt[i])if(v[i]!=pre)nd[u].x++,dfs(v[i],u);28 }29 30 int main(){31 scanf("%d",&t);32 while(t--)33 {34 printf("Case #%d:\n",ic++);35 init();36 scanf("%d%d",&n,&q);37 F(i,1,n-1)38 {39 int x,y;40 scanf("%d%d",&x,&y);41 adg(x,y),adg(y,x);42 }43 dfs();44 F(i,1,q)45 {46 int nn,x;47 int ans=0;48 scanf("%d",&nn);49 F(j,1,nn)scanf("%d",&x),tmp[j]=nd[x];50 sort(tmp+1,tmp+1+nn);51 F(j,1,nn)hsh[tmp[j].idx]=j;52 F(j,1,nn)53 {54 if(tmp[j].x-tmp[j].n<2)tmp[j].col=0;55 if(tmp[j].x-tmp[j].n==0)tmp[hsh[nd[tmp[j].idx].pre]].n++;56 }57 F(j,1,nn)58 {59 if(tmp[j].col==1)ans++;60 hsh[tmp[j].idx]=0;61 }62 printf("%d\n",ans+n-nn);63 }64 }65 return 0;66 }
hdu_5927_Auxiliary Set(xjb搞)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。