计蒜客 Red Black Tree(树形DP)
You are given a rooted tree with n nodes. The nodes are numbered 1..n. The root is node 1, and m of the nodes are colored red, the rest are black.
You would like to choose a subset of nodes such that there is no node in your subset which is an ancestor of any other node in your subset. For example, if A is the parent of B and B is the parent of C, then you could have at most one of A, B or C in your subset. In addition, you would like exactly k of your chosen nodes to be red.
If exactly mm of the nodes are red, then for all k = 0..m, figure out how many ways you can choose subsets with k red nodes, and no node is an ancestor of any other node.
Input Format
Each input will consist of a single test case.
Note that your program may be run multiple times on different inputs.
Each test case will begin with a line with two integers n(1≤n≤2×10^5) and m(0≤m≤min(10^3,n)), where n is the number of nodes in the tree, and m is the number of nodes which are red. The nodes are numbered 1..n.
Each of the next n - 1 lines will contain a single integer p(1≤p≤n), which is the number of the parent of this node. The nodes are listed in order, starting with node 2, then node 3, and so on. Node 1 is skipped, since it is the root. It is guaranteed that the nodes form a single tree, with a single root at node 1 and no cycles.
Each of the next m lines will contain single integer r(1≤r≤n). These are the numbers of the red nodes. No value of r will be repeated.
Output Format
Output m + 1 lines, corresponding to the number of subsets satisfying the given criteria with a number of red nodes equal to k = 0..m, in that order. Output this number modulo 10^9 + 7.
样例输入1
4 1
1
1
1
3
样例输出1
5
4
样例输入2
4 4
1
1
1
1
2
3
4
样例输出2
1
4
3
1
0
样例输入3
14 4
1
2
1
2
3
4
5
5
13
8
10
4
4
8
3
12
13
样例输出3
100
169
90
16
0
题意
一棵树,n个点,其中有m个红色,其余为黑点,1为根,选1个点集合,集合内的任意两点不互为祖先,问集合内红色节点的个数为0-m的方案数。
题解
dp[root][m]代表根为root的子树红色节点为m的方案数。
不选root,dp[root][0]=1,考虑子树son的情况,考虑h[M]代表组成M的方案数,相当于每次一颗子树把里面的所有红色节点一个一个压进去,类似于背包。
选root,dp[root][red[root]]++,相当于下面都不能选。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=;
const int M=;
const int MD=;
int dp[N][M],h[M],red[N],sz[N];
int n,m;
vector<int>G[N];
void dfs(int u){
dp[u][]=;
sz[u]=red[u];
for(int i=;i<G[u].size();i++) {
int v=G[u][i];
dfs(v);
int up=min(sz[u]+sz[v],m);
for(int j=;j<=up;j++)h[j]=;
for(int j=;j<=sz[v];j++)
for(int k=;k<=sz[u]&&j+k<=up;k++)
h[j+k]=(h[j+k]+1LL*dp[v][j]*dp[u][k])%MD;
sz[u]+=sz[v];
for(int j=;j<=sz[u];j++)dp[u][j]=h[j];
}
dp[u][red[u]]=(dp[u][red[u]]+)%MD;
}
int main() {
scanf("%d%d",&n,&m);
for(int i=,u;i<=n;i++) {
scanf("%d",&u);
G[u].push_back(i);
}
for(int i=,x;i<m;i++) {
scanf("%d",&x);
red[x]=;
}
dfs();
for(int i=;i<=m;i++)
printf("%d\n",dp[][i]);
return ;
}
最新文章
- 我的MYSQL学习心得(十) 自定义存储过程和函数
- Matlab中double,im2double,mat2gray区别
- H264编码原理以及I帧、B和P帧详解
- 如何在Linux服务器中隐藏PHP版本
- [整理]Matlab之中心平滑滤波
- linux tomcat配置https
- windows系统中ubuntu虚拟机安装及web项目到服务上(三)
- fastboot 教程
- ha_innobase::rnd_next
- The Doors - POJ 1556 (线段相交)
- sql server去除重复信息,
- 关于sqlserver还原不了数据库的原因
- 2015浙江财经大学ACM有奖周赛(一) 题解报告
- SQL Server 给表和字段添加说明
- ArcGIS JS Api 4.x修改三维球背景技巧
- Xamarin 开发过的那些项目
- 【原创】大叔经验分享(20)spark job之间会停顿几分钟
- vue及Eelement使用过程中遇到的一些问题
- BLEU (Bilingual Evaluation Understudy)
- canvas动画---- 太阳、地球、月球