HDU 5927 Auxiliary Set (DFS+模拟)
来源:互联网 发布:淘宝店铺添加视频教程 编辑:程序博客网 时间:2024/06/05 00:43
Auxiliary Set
Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1934 Accepted Submission(s): 564
Problem Description
Given a rooted tree with n vertices, some of the vertices are important.
An auxiliary set is a set containing vertices satisfying at least one of the two conditions:
∙ It is an important vertex
∙ It is the least common ancestor of two different important vertices.
You are given a tree with n vertices (1 is the root) and q queries.
Each query is a set of nodes which indicates the unimportant vertices in the tree. Answer the size (i.e. number of vertices) of the auxiliary set for each query.
An auxiliary set is a set containing vertices satisfying at least one of the two conditions:
You are given a tree with n vertices (1 is the root) and q queries.
Each query is a set of nodes which indicates the unimportant vertices in the tree. Answer the size (i.e. number of vertices) of the auxiliary set for each query.
Input
The first line contains only one integer T (T≤1000 ), which indicates the number of test cases.
For each test case, the first line contains two integers n (1≤n≤100000 ), q (0≤q≤100000 ).
In the following n -1 lines, the i-th line contains two integersui,vi(1≤ui,vi≤n) indicating there is an edge between ui i and vi in the tree.
In the next q lines, the i-th line first comes with an integermi(1≤mi≤100000) indicating the number of vertices in the query set.Then comes with mi different integers, indicating the nodes in the query set.
It is guaranteed that∑qi=1mi≤100000 .
It is also guaranteed that the number of test cases in whichn≥1000 or ∑qi=1mi≥1000 is no more than 10.
For each test case, the first line contains two integers n (
In the following n -1 lines, the i-th line contains two integers
In the next q lines, the i-th line first comes with an integer
It is guaranteed that
It is also guaranteed that the number of test cases in which
Output
For each test case, first output one line "Case #x:", where x is the case number (starting from 1).
Then q lines follow, i-th line contains an integer indicating the size of the auxiliary set for each query.
Then q lines follow, i-th line contains an integer indicating the size of the auxiliary set for each query.
Sample Input
16 36 42 55 41 55 33 1 2 31 53 3 1 4
Sample Output
Case #1:363HintFor the query {1,2, 3}:•node 4, 5, 6 are important nodes For the query {5}:•node 1,2, 3, 4, 6 are important nodes•node 5 is the lea of node 4 and node 3 For the query {3, 1,4}:• node 2, 5, 6 are important nodes
Source
2016CCPC东北地区大学生程序设计竞赛 - 重现赛
题意是给定一棵树,给出q次询问,每次给定一个集合,集合中的数为不重要的数,其他数为重要数,但是如果一个不重要数的孩子有两个及两个以上的是重要数,那么这个数也是一个重要数,问最后有多少的重要数。
显然除集合内的题都是重要数,需要确定的是集合内的数是否是重要数,然后就在搞集合内的重要数,然后就花样超时,实在是搞不懂为什么花样超时,也实在搞不懂为什么随便一交就AC,莫名AC。对于不重要数,需要判断它的孩子是否有两个以上的重要数,dfs求的当前结点的 孩子数和当前结点的父结点都可以想到,但之后有一步优化,因为每次都是输入一个集合,为了确保当前结点的后效性,需要从最后一层结点向上遍历,此时需要在dfs中记录当前结点在这棵树中的层数,然后对输入的m个点进行sort排序,让后进入树的结点排在前面,优先遍历。
遍历时需要记录当前结点的父结点,如果此结点的重要孩子数>=2,则ans++,如果此结点的重要孩子数==0,那么这个点对其父节点没有贡献,则此父结点孩子数--,因为下一次要恢复孩子数,所以用另一个数组记录减去了多少孩子,最后将这些孩子的数量再加上,最后输出n-m+ans.
代码实现:
#include <stdio.h>#include <math.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>#include <string>#include <queue>#include <stack>#include <vector>#include <set>#include <map>#define mset(a,i) memset(a,i,sizeof(a))using namespace std;typedef long long ll;const int INF=0x3f3f3f3f;const int mod=1e9+7;const int MAX=505050;const double eps=1e-6;int dir[4][2]={1,0,0,1,-1,0,0,-1};inline void SS(char*s){scanf("%s",s);}inline ll SI(){ll x;scanf("%lld",&x);return x;}inline ll P(ll x){printf("%lld\n",x);}inline ll qpow(ll n,ll m){n%=mod;ll ans=1;while(m){if(m%2)ans=(ans*n)%mod;m/=2;n=(n*n)%mod;}return ans;}inline ll inv(ll b){return b==1?1:(mod-mod/b)*inv(mod%b)%mod;}inline ll inv2(ll b){return qpow(b,mod-2);}struct node{ int s,t,next;}e[MAX];int head[MAX],cnt;void add(int u,int v){ e[cnt]=node{u,v,head[u]}; head[u]=cnt++;}int vis[MAX];int fa[MAX];int child[MAX];int a[MAX],b[MAX],c[MAX];int vf[MAX];void dfs(int root,int dad,int index){ c[root]=index; fa[root]=dad; child[root]=0; for(int i=head[root];~i;i=e[i].next) { int t=e[i].t; if(t!=dad) { child[root]++; dfs(t,root,index+1); } }}int cmp(int a,int b){ return c[a]>c[b];}int main(){ int T,r=1,n,q,u,v,m; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&q); memset(head,-1,sizeof(int)*(n+2)); cnt=0; for(int i=1;i<n;i++) { scanf("%d%d",&u,&v); add(u,v); add(v,u); } printf("Case #%d:\n",r++); memset(vis,-1,sizeof(int)*(n+2)); memset(vf,-1,sizeof(int)*(n+2)); dfs(1,-1,1); mset(b,0); while(q--) { scanf("%d",&m); int ans=0; for(int i=1;i<=m;i++) scanf("%d",&a[i]); sort(a+1,a+1+m,cmp); for(int i=1;i<=m;i++) { int temp=fa[a[i]]; if(temp==-1&&child[a[i]]>=2) ans++; if(temp==-1) continue; if(child[a[i]]>=2) ans++; if(child[a[i]]==0) { child[temp]--; b[temp]++; } } printf("%d\n",n-m+ans); for(int i=1;i<=m;i++) { int temp=fa[a[i]]; if(b[temp]) { child[temp]+=b[temp]; b[temp]=0; } } } } return 0;}
阅读全文
0 0
- HDU 5927 Auxiliary Set (DFS+模拟)
- hdu 5927 Auxiliary Set dfs
- hdu 5927 Auxiliary Set (dfs)
- HDU 5927 Auxiliary Set dfs(思维)
- HDU 5927 Auxiliary Set DFS好题
- HDU 5927 Auxiliary Set(DFS)
- hdu 5927 Auxiliary Set dfs+逆向思维
- hdu 5927 Auxiliary Set
- hdu 5927 Auxiliary Set
- HDU 5927 Auxiliary Set
- HDU 5927Auxiliary Set
- [HDU 5927] Auxiliary Set (DFS+树上LCA)
- HDU 5927 Auxiliary Set(dfs+逆向思维)
- HDU 5927 Auxiliary Set 最近公共祖先 (dfs)
- F - Auxiliary Set HDU - 5927
- HDU5927 Auxiliary Set(dfs)
- HDU 5927 Auxiliary Set 【DFS+树】(2016CCPC东北地区大学生程序设计竞赛)
- HDU 5927 Auxiliary Set【DFS】(2016CCPC东北赛F题)
- 男同社交软件Zank如何杀出红海拿到B轮融资的?
- windows主线程等待子线程退出卡死问题
- IT已死!联想和HTC能否涅槃重生?
- PHP开发者大会看房产O2O:技术将成为变革的重要驱动力
- 丰田“友情收购”波士顿动力,汽车公司更适合造机器人?
- HDU 5927 Auxiliary Set (DFS+模拟)
- PRML学习笔记-线性回归 Linear Regression
- Python 爬取豆瓣电影Top250(一)
- 接盘侠还是捡漏?丰田研究所收购波士顿动力分析
- 让我们坐上巴铁,回2010年看看当时的科技最佳发明
- 腾讯副总裁王波:连接释放潜力,“互联网+”为警务创新赋能
- nginx配置缓存限流
- Django错误:AttributeError: 'WSGIRequest' object has no attribute 'Post'
- SpringMVC之分析AnnotationDrivenBeanDefinitionParser(一)