HDU 5927 Auxiliary Set (dfs)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5927

题意:

给你一棵树,其中有一些’不重要‘的点,要是这些’不重要‘的点的子树中有两个重要的点的LCA是这个点,那么这个点就是重要的点。每次询问 问你重要的点有多少?

思路:

用不重要的点建图,要是这个不重要点上的相邻子树至少有两个有重要的点不在同一子树上,那么这个不重要的点才变成重要的点。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <vector>
  5 #include <map>
  6 using namespace std;
  7 const int N = 1e5 + 5;
  8 vector <int> G[N];
  9 int d[N], a[N], par[N], d2[N], cnt, son[N];
 10 bool vis[N];
 11 //son[u]表示u节点相邻的子树个数
 12 //原图:d[u]表示以u节点为root的子树节点个数
 13 //不重要点建的图:d2[u]表示以u节点为root的子树节点个数
 14 //cnt表示不重要的点的个数
 15
 16 void init(int n) {
 17     for(int i = 1; i <= n; ++i) {
 18         G[i].clear();
 19         vis[i] = false;
 20     }
 21 }
 22
 23 void dfs1(int u, int p) {
 24     d[u] = 1;
 25     par[u] = p;
 26     son[u] = 0;
 27     for(int i = 0; i < G[u].size(); ++i) {
 28         int v = G[u][i];
 29         if(v == p)
 30             continue;
 31         dfs1(v, u);
 32         d[u] += d[v];
 33         ++son[u];
 34     }
 35 }
 36
 37 void dfs2(int u) {
 38     d2[u] = 1;
 39     vis[u] = true;
 40     int num = 0, num2 = 0;
 41     for(int i = 0; i < G[u].size(); ++i) {
 42         int v = G[u][i];
 43         if(!vis[v])
 44             dfs2(v);
 45         d2[u] += d2[v];
 46         if(d[v] > d2[v]) {
 47             ++num;
 48         }
 49         num2++;
 50     }
 51     if(num + (son[u] - num2) > 1) //符合条件 (不同子树中重要点)>=2;
 52         return ;
 53     else
 54         cnt++;
 55 }
 56
 57 int main()
 58 {
 59     int t, n, m, u, v, q;
 60     scanf("%d", &t);
 61     for(int ca = 1; ca <= t; ++ca) {
 62         scanf("%d %d", &n, &m);
 63         init(n);
 64         for(int i = 1; i < n; ++i) {
 65             scanf("%d %d", &u, &v);
 66             G[u].push_back(v);
 67             G[v].push_back(u);
 68         }
 69         printf("Case #%d:\n", ca);
 70         dfs1(1, 0);
 71         init(n);
 72         while(m--) {
 73             scanf("%d", &q);
 74             for(int i = 1; i <= q; ++i) {
 75                 scanf("%d", a + i);
 76                 vis[a[i]] = true;
 77             }
 78             for(int i = 1; i <= q; ++i) {
 79                 if(vis[par[a[i]]]) {
 80                     G[par[a[i]]].push_back(a[i]);
 81                 }
 82             }
 83             for(int i = 1; i <= q; ++i) {
 84                 vis[a[i]] = false;
 85             }
 86             cnt = 0;
 87             for(int i = 1; i <= q; ++i) {
 88                 if(!vis[a[i]]) {
 89                     dfs2(a[i]);
 90                 }
 91             }
 92             for(int i = 1; i <= q; ++i) {
 93                 vis[a[i]] = false;
 94                 G[a[i]].clear();
 95             }
 96             printf("%d\n", n - cnt);
 97         }
 98     }
 99     return 0;
100 }
时间: 2024-12-24 09:21:34

HDU 5927 Auxiliary Set (dfs)的相关文章

HDU 5927 Auxiliary Set 【DFS+树】(2016CCPC东北地区大学生程序设计竞赛)

Auxiliary Set Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 873    Accepted Submission(s): 271 Problem Description Given a rooted tree with n vertices, some of the vertices are important. An a

hdu 5927 Auxiliary Set 贪心

Auxiliary Set Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) 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

hdu 1501 Zipper (dfs+记忆化搜索)

Zipper Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6491    Accepted Submission(s): 2341 Problem Description Given three strings, you are to determine whether the third string can be formed

hdu 1518 Square (dfs搜索可参考poj1011)

Square Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8589    Accepted Submission(s): 2784 Problem Description Given a set of sticks of various lengths, is it possible to join them end-to-end

hdu 5167 Fibonacci(DFS)

hdu 5167 Fibonacci 问题描述 斐波那契数列的递归定义如下: Fi=???01Fi?1+Fi?2i = 0i = 1i > 1 现在我们需要判断一个数是否能表示为斐波那契数列中的数的乘积. 输入描述 有多组数据,第一行为数据组数T(T≤100,000). 对于每组数据有一个整数n,表示要判断的数字. 0≤n≤1,000,000,000 输出描述 对于每组数据,如果可以输出"Yes",否则输出"No". 输入样例 3 4 17 233 输出样例

HDU 3158 PropBot(DFS)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3158 Problem Description You have been selected to write the navigation module for PropBot. Unfortunately, the mechanical engineers have not provided a lot of flexibility in movement; indeed, the PropBot

hdu 4499 Cannon 暴力dfs搜索

Cannon Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 589    Accepted Submission(s): 338 Problem Description In Chinese Chess, there is one kind of powerful chessmen called Cannon. It can move

Hdu 1175 连连看(DFS)

Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1175 因为题目只问能不能搜到,没问最少要几个弯才能搜到,所以我采取了DFS. 因为与Hdu 1728相比,都要考虑转弯次数,所以在判断转弯的次数上,两者可以相互借鉴. 这一点应该不难想到,在搜索前就应判断两点的值是否相等,以及两点的值中是否有0.如果不相等或其中一值为0,则可以判断是"NO". 时间虽是10000ms,但只是这样,还是超时. 后来又加了一个数组walk[][],用

HDU 5379 Mahjong tree(dfs)

题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=5379 Problem Description Little sun is an artist. Today he is playing mahjong alone. He suddenly feels that the tree in the yard doesn't look good. So he wants to decorate the tree.(The tree has n verte