Codechef Black Nodes in Subgraphs(树型背包)

题目链接 Black Nodes in Subgraphs

题目意思就是在一棵树中所有点标记为两种颜色(黑和白)

然后询问是否存在大小为X恰好有Y个黑点的连通块

这题我们可以用树型背包的方法

设$f[i][j][0]$为以$i$为根的子树中大小为$j$的连通块的黑点数目的最小值,该连通块必须经过$i$

$f[i][j][1]$为以$i$为根的子树中大小为$j$的连通块的黑点数目的最大值,该连通块必须经过$i$

那么转移的时候有

$f[x][i + j][0] = min(f[x][i + j][0], f[x][i][0] + f[u][j][0]);$
$f[x][i + j][1] = max(f[x][i + j][1], f[x][i][1] + f[u][j][1]);$

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 #define rep(i, a, b)    for (int i(a); i <= (b); ++i)
 6 #define dec(i, a, b)    for (int i(a); i >= (b); --i)
 7
 8 const int N = 5010;
 9 int f[N][N][2], sz[N];
10 vector <int> v[N];
11 int T, n, q;
12 int c[N], F[N], G[N];
13
14 void dfs(int x, int fa){
15     sz[x] = 1;
16     if (c[x]) f[x][1][0] = f[x][1][1] = 1;
17     else      f[x][1][0] = f[x][1][1] = 0;
18
19     for (auto u : v[x]){
20         if (u == fa) continue;
21         dfs(u, x);
22         dec(i, sz[x], 1){
23             rep(j, 1, sz[u]){
24                 f[x][i + j][0] = min(f[x][i + j][0], f[x][i][0] + f[u][j][0]);
25                 f[x][i + j][1] = max(f[x][i + j][1], f[x][i][1] + f[u][j][1]);
26             }
27         }
28
29         sz[x] += sz[u];
30     }
31
32     rep(i, 1, sz[x]){
33         F[i] = min(F[i], f[x][i][0]);
34         G[i] = max(G[i], f[x][i][1]);
35     }
36 }
37
38 int main(){
39
40     scanf("%d", &T);
41     while (T--){
42         scanf("%d%d", &n, &q);
43         rep(i, 0, n) v[i].clear();
44         memset(sz, 0, sizeof sz);
45         rep(i, 0, n) rep(j, 0, n) f[i][j][0] = 1 << 27, f[i][j][1] = 0;
46         rep(i, 0, n) F[i] = 1 << 27, G[i] = 0;
47
48         rep(i, 1, n - 1){
49             int x, y;
50             scanf("%d%d", &x, &y);
51             v[x].push_back(y);
52             v[y].push_back(x);
53         }
54
55         rep(i, 1, n) scanf("%d", c + i);
56         dfs(1, 0);
57
58         for (; q--; ){
59             int x, y;
60             scanf("%d%d", &x, &y);
61             puts(F[x] <= y && G[x] >= y ? "Yes" : "No");
62         }
63     }
64
65     return 0;
66
67 }
时间: 2024-10-25 17:44:34

Codechef Black Nodes in Subgraphs(树型背包)的相关文章

二叉苹果树(树型DP+背包)

二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点).这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树: 2   5 \  / 3  4 \  / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 程序名:apple 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<N<=

HDU1561 The more, The Better(树型DP)

题目是有n个存有宝藏的城堡,攻克任何一个城堡都需要先攻克0个或其他1个城堡,问攻克m个城堡最多能得到多少宝藏. 题目给的城堡形成一个森林,添加一个超级根把森林连在一起就是树了,那么就考虑用树型DP: dp[u][m]表示以u结点为根的子树攻克m个结点的最大价值 但是这样转移太难了,根是从每个孩子通过各自分配若干的城堡去攻克转移的,一个排列组合数,阶乘,是指数级的时间复杂度! 看了题解,原来这是依赖背包,没看背包九讲..不过网上的博客似乎没说清楚,事实上这个状态应该是三个维度来表示: dp[u][

【HDOJ 5834】Magic boy Bi Luo with his excited tree(树型DP)

[HDOJ 5834]Magic boy Bi Luo with his excited tree(树型DP) Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description Bi Luo is a magic boy, he also has a migic tree,

一种理想的在关系数据库中存储树型结构数据的方法

一种理想的在关系数据库中存储树型结构数据的方法 在各种基于关系数据库的应用系统开发中,我们往往需要存储树型结构的数据,目前有很多流行的方法,如邻接列表模型(The Adjacency List Model),在此基础上也有很多人针对不同的需求做了相应的改进,但总是在某些方面存在的各种各样的缺陷.    那么理想中的树型结构应具备哪些特点呢?数据存储冗余小.直观性强:方便返回整个树型结构数据:可以很轻松的返回某一子树(方便分层加载):快整获以某节点的祖谱路径:插入.删除.移动节点效率高等等.带着这

【POJ 2486】 Apple Tree(树型dp)

[POJ 2486] Apple Tree(树型dp) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8981   Accepted: 2990 Description Wshxzt is a lovely girl. She likes apple very much. One day HX takes her to an apple tree. There are N nodes in the tree. Each

[HAOI2010][BZOJ2427] 软件安装|tarjan|树型dp

2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 463  Solved: 194[Submit][Status][Discuss] Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是现在有个问题:软件之间存在依赖关系,即软件i只有在安装了软件j(

树型动态规划练习总结

类型一.多叉树转二叉树进行资源分配 例如: * 例1. 选课:每门课可能有一门先选课,即某些课必须在另外的某节课被选之后才能选,每门课能得的学分不同,求最大学分. * 例2. 通向自由的钥匙:可以从一个房间通向另外多个房间,通过每个房间所需的花费不同,得到的价值也不同,用最小花费获得最大价值. 这种题目的特点是需要在多叉树上进行资源的分配,对不同的子树分配不同的资源,以求最大价值.可以直接在多叉树上用背包的方式求解,但是更常用的方法是用左孩子右兄弟表示法转化为二叉树. 转化之后的通用状态转移方程

树型部件分层加载数据实现思路,提高速度,提高效率

我们知道,树型部件中可以以树型展示数据出来.例如我们把组织机构展示出来,可以写业务表:select  dept_id,dept_name,upper_id from sa_dept_dict然后再设置树型关键列未 dept_id,上级列未upper_id.这样就出来了一个树型的数据. 这样在一般业务中是没有问题的,如果我们设想一下sa_dept_dict表中有成千上万条数据,这样直接一下全部读出来形成一棵树,效率可能就很慢.那如何来解决较好呢. 我们知道因为树型是可以一个一个节点展开的,那就可以

初学树型dp

树型DP DFS的回溯是树形DP的重点以及核心,当回溯结束后,root的子树已经被遍历完并处理完了.这便是树形DP的最重要的特点 自己认为应该注意的点 好多人都说在更新当前节点时,它的儿子结点都给更新完了,实际上这并不准确.对于当前节点,我们需要dfs它的儿子,并且在dfs中进行dp.在此过程中并不是等到儿子都更新完我们才更新当前节点的信息(假设当前节点为x, 有儿子son1 , son2, son3, 且son1已经更新完了, 即x已有了son1的信息, son2刚刚更新完,即dfs正在son