Codeforces Round #263 (Div. 2) D. Appleman and Tree(树形DP)
2014-08-27 16:28
459 查看
题目链接
memory limit per test: 256 megabytes
input :standard input
output:standard output
Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices are colored white.
Consider a set consisting of k (0 ≤ k < n) edges of Appleman's tree. If Appleman deletes these edges from the tree, then it will split into(k + 1) parts. Note, that each part will be a tree with colored vertices.
Now Appleman wonders, what is the number of sets splitting the tree in such a way that each resulting part will have exactly one black vertex? Find this number modulo 1000000007 (109 + 7).
Input
The first line contains an integer n (2 ≤ n ≤ 105) — the number of tree vertices.
The second line contains the description of the tree: n - 1 integers p0, p1, ..., pn - 2 (0 ≤ pi ≤ i). Where pi means that there is an edge connecting vertex (i + 1) of the tree and vertex pi. Consider tree vertices are numbered from 0 to n - 1.
The third line contains the description of the colors of the vertices: n integers x0, x1, ..., xn - 1 (xi is either 0 or 1). If xi is equal to 1, vertex i is colored black. Otherwise, vertex i is colored white.
Output
Output a single integer — the number of ways to split the tree modulo 1000000007 (109 + 7).
Sample test(s)
input
output
input
output
input
output
题意:对每个节点染色,白或者黑,问你断开某些边,使得每个联通块都恰好只有一个节点时黑色,问有多少种断边方式。
思路 :树形DP, dp[i][0]代表到 i 这个点它所在的子树只有一个黑点的情况,dp[i][0] 包含i节点的这部分没有黑点的情况数。
对于每个节点 i,计算到它的一个子树(根节点u) (设连接的边为edge)的时候,dp[i][0] 为dp[i][0] * dp[u][1] + dp[i][0] * dp[u][0], 已处理完的一定要取dp[i][0], 如果取edge 则子树取dp[u][0],如果不取edge, 则子树取dp[u][1].
dp[i][1] 为 dp[i][1] *(dp[u][0] + dp[u][1]) + dp[i][0] *dp[u][1] , 如果处理完的取dp[i][1],edge取的话为dp[u][0], 不取的话为dp[u][1]; 如果处理完的取dp[i][0], edge一定要取且要乘以dp[u][1] (ps: dp[u][0] 不能要,如果要的话 u点的部分会出现不含黑点的情况)
View Code
D. Appleman and Tree
time limit per test :2 secondsmemory limit per test: 256 megabytes
input :standard input
output:standard output
Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices are colored white.
Consider a set consisting of k (0 ≤ k < n) edges of Appleman's tree. If Appleman deletes these edges from the tree, then it will split into(k + 1) parts. Note, that each part will be a tree with colored vertices.
Now Appleman wonders, what is the number of sets splitting the tree in such a way that each resulting part will have exactly one black vertex? Find this number modulo 1000000007 (109 + 7).
Input
The first line contains an integer n (2 ≤ n ≤ 105) — the number of tree vertices.
The second line contains the description of the tree: n - 1 integers p0, p1, ..., pn - 2 (0 ≤ pi ≤ i). Where pi means that there is an edge connecting vertex (i + 1) of the tree and vertex pi. Consider tree vertices are numbered from 0 to n - 1.
The third line contains the description of the colors of the vertices: n integers x0, x1, ..., xn - 1 (xi is either 0 or 1). If xi is equal to 1, vertex i is colored black. Otherwise, vertex i is colored white.
Output
Output a single integer — the number of ways to split the tree modulo 1000000007 (109 + 7).
Sample test(s)
input
3 0 0 0 1 1
output
2
input
6 0 1 1 0 4 1 1 0 0 1 0
output
1
input
10 0 1 2 1 4 4 4 0 8 0 0 0 1 0 1 1 0 0 1
output
27
题意:对每个节点染色,白或者黑,问你断开某些边,使得每个联通块都恰好只有一个节点时黑色,问有多少种断边方式。
思路 :树形DP, dp[i][0]代表到 i 这个点它所在的子树只有一个黑点的情况,dp[i][0] 包含i节点的这部分没有黑点的情况数。
对于每个节点 i,计算到它的一个子树(根节点u) (设连接的边为edge)的时候,dp[i][0] 为dp[i][0] * dp[u][1] + dp[i][0] * dp[u][0], 已处理完的一定要取dp[i][0], 如果取edge 则子树取dp[u][0],如果不取edge, 则子树取dp[u][1].
dp[i][1] 为 dp[i][1] *(dp[u][0] + dp[u][1]) + dp[i][0] *dp[u][1] , 如果处理完的取dp[i][1],edge取的话为dp[u][0], 不取的话为dp[u][1]; 如果处理完的取dp[i][0], edge一定要取且要乘以dp[u][1] (ps: dp[u][0] 不能要,如果要的话 u点的部分会出现不含黑点的情况)
#include <stdio.h> #include <string.h> #include <iostream> #define mod 1000000007 using namespace std ; struct node { int u ; int v ; int next ; }p[100010]; int cnt,head[100010],color[100010] ; long long dp[100010][2] ; void addedge(int u,int v) { p[cnt].u = u ; p[cnt].v = v ; p[cnt].next = head[u] ; head[u] = cnt ++ ; } void DFS(int u) { dp[u][color[u]] = 1 ; for(int i = head[u] ; i+1 ; i = p[i].next) { int v = p[i].v ; DFS(v) ; dp[u][1] = ((dp[u][1] * dp[v][0]) % mod + (dp[u][1] * dp[v][1]) % mod + (dp[u][0] * dp[v][1]) % mod) % mod ; dp[u][0] = ((dp[u][0] * dp[v][0]) % mod + (dp[u][0] * dp[v][1]) % mod) % mod ; } } int main() { int n ,a; while(~scanf("%d",&n)) { cnt = 0 ; memset(head,-1,sizeof(head)) ; memset(dp,0,sizeof(dp)) ; for(int i = 1 ; i < n ; i++) { scanf("%d",&a) ; addedge(a,i) ; } for(int i = 0 ; i < n ; i++) scanf("%d",&color[i]) ; DFS(0) ; printf("%I64d\n",dp[0][1]) ; } return 0 ; }
View Code
相关文章推荐
- codeforces Round #263(div2) D. Appleman and Tree 树形dp
- 【Codeforces Round 263 (Div 2)D】【树形DP】Appleman and Tree 树上割k个黑点为k块的方案数
- Codeforces Round #263 Div.1 B Appleman and Tree --树形DP【转】
- Codeforces Round #263 Div.1 B Appleman and Tree --树形DP【转】
- Codeforces Round #263 (Div. 1) B. Appleman and Tree( 树形DP )
- Codeforces Round #263 Appleman and Tree(树形DP)
- codeforces 462 d Appleman and Tree(树形dp)
- CF 462D(Appleman and Tree-树形dp)
- CF 461B - Appleman and Tree(树形DP)
- codeforces 461B B. Appleman and Tree(树形dp)
- Appleman and Tree - CodeForces 461 B 树形dp
- Codeforces Round #263 (Div. 1) B. Appleman and Tree
- Codeforces Round #263 (Div. 1) B. Appleman and Tree(给一棵树,每个点为白色或黑色,切断一些边,使得每个连通块有且仅有一个黑点,问划分方案数。)
- Codeforces 461B - Appleman and Tree 树状DP
- Codeforces Round #263 (Div. 1) B. Appleman and Tree
- Codeforces 461B - Appleman and Tree 树状DP
- Codeforces Round #263 (Div.1) B. Appleman and Tree
- Codeforces Round #382 (Div. 1) C. Ostap and Tree(树形DP)
- Codeforces Round #275 (Div. 1) D Random Function and Tree 树形dp
- 【树形dp】Codeforces Round #405 (rated, Div. 1, based on VK Cup 2017 Round 1) B. Bear and Tree Jumps