HDU 5927 Auxiliary Set 最近公共祖先
来源:互联网 发布:windows找不到javaw 编辑:程序博客网 时间:2024/06/10 19:42
Auxiliary Set
Time Limit: 9000/4500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 964 Accepted Submission(s): 302
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东北地区大学生程序设计竞赛 - 重现赛
题目大意:
给出 整棵树。给出 k 个点, 这 k 个点是不重要的点。
需要求的是一个集合的大小,满足下面两个条件可以放入这个集合中
1. 重要的点
2. 如果某个不重要点有两个儿子为 重要的点 ,那么也放入这个集合中。
输出 集合的大小。
思路:
dfs 处理好每个点有多少个儿子。
然后对于所有不重要的点,按照深度进行从大到小排序。
从深度最大的开始检索。如果当前节点的儿子数量大于 等于2 那么当前点可以放入集合中。
如果当前点 没有儿子 那么我们可以暂时删掉这个点(将其父亲 的儿子节点的数量减 1)(如果他的父节点有两个儿子,一个为重要的,一个为不重要的,并且这个不重要的
节点没有儿子节点了 那么这个父亲节点是不重要的点,虽然他有两个儿子,但是他只有一个重要的儿子)
检索完就可以了
AC代码:
#include<bits/stdc++.h>using namespace std;int n,m,q;int head[200005];int tot;int nextt[200005];int num[200005];int ff[100005];int son[100005];int tt[100005];int eenum[100005];struct node{ int a; int dep; friend bool operator < (const node &aa,const node &b) { return aa.dep>b.dep; }}haha[100005];bool cmp(int x,int y){ return haha[x].dep>haha[y].dep;}void add(int u,int v){ num[tot]=u; nextt[tot]=head[v]; head[v]=tot; tot++; num[tot]=v; nextt[tot]=head[u]; head[u]=tot; tot++;}void dfs(int u,int f){ ff[u]=f; haha[u].dep=haha[f].dep+1; son[u]=0; int t; for(t=head[u];t!=-1;t=nextt[t]) { if(num[t]!=f) { dfs(num[t],u); son[u]++; } }}int main(){ int T; int ca=1; scanf("%d",&T); int a,b; while(T--) { scanf("%d%d",&n,&m); tot=0; for(int i=0;i<=n;i++) { head[i]=-1; } haha[0].dep=0; for(int i=0;i<n-1;i++) { scanf("%d%d",&a,&b); add(a,b); } dfs(1,0); int ans; printf("Case #%d:\n", ca); ca++; while(m--) { scanf("%d",&q); ans=n-q; for(int i=0;i<q;i++) { scanf("%d",&eenum[i]); } sort(eenum,eenum+q,cmp); for(int i=0;i<q;i++) { tt[eenum[i]]=son[eenum[i]]; } for(int i=0;i<q;i++) { if(tt[eenum[i]]>=2) { ans++; } else if(tt[eenum[i]]==0) { tt[ff[eenum[i]]]--; } } cout<<ans<<endl; } }}
0 0
- HDU 5927 Auxiliary Set 最近公共祖先
- HDU 5927 Auxiliary Set 最近公共祖先 (dfs)
- CCPC-东北地区-Auxiliary Set(最近公共祖先变形)
- hdu 5927 Auxiliary Set
- hdu 5927 Auxiliary Set
- HDU 5927 Auxiliary Set
- HDU 5927Auxiliary Set
- hdu 2586 最近公共祖先
- hdu 2586 最近公共祖先
- hdu 2586 最近公共祖先
- hdu 5927 Auxiliary Set dfs
- F - Auxiliary Set HDU - 5927
- hdu 5927 Auxiliary Set (dfs)
- HDU 5927 (最近公共祖先)(bfs+树)
- HDU 2874 LCA 最近公共祖先
- hdu 2586(最近公共祖先LCA)
- How far away ?+hdu+最近公共祖先
- hdu 2586 最近公共祖先 LCA
- 51nod 1080 两个数的平方和
- C++ STL list
- 那些只有上帝才能看到的背影
- 堆
- Leetcode-162. Find Peak Element
- HDU 5927 Auxiliary Set 最近公共祖先
- 51nod 1081 子段求和
- HDOJ 5945 Fxx and game
- Jupyter Notebook的快捷键
- mybatis 循环
- 51nod 1082 与7无关的数
- java多线程常用方法
- 进程池终章--终于可以说自己对进程池了解了。。。
- cvGet2D使用的注意事项