Codeforces Round #263 (Div. 2) D. Appleman and Tree 树形dp

链接:

http://codeforces.com/contest/462/problem/D

题意:

给定n个点的树,

0为根,下面n-1行表示每个点的父节点

最后一行n个数 表示每个点的颜色,0为白色,1为黑色。

把树分成若干个联通块使得每个联通块有且仅有一个黑点,问有多少种分法(结果mod1e9+7)

题解:

树形dp,每个点有2个状态,已经归属于某个黑点和未归属于某个黑点。

代码:

31 int n;
32 int x[MAXN];
33 VI G[MAXN];
34 ll dp[MAXN][2];
35
36 void dfs(int u) {
37     if (x[u]) dp[u][1] = 1;
38     else dp[u][0] = 1;
39     rep(i, 0, G[u].size()) {
40         int v = G[u][i];
41         dfs(v);
42         ll old[2] = { dp[u][0], dp[u][1] };
43         dp[u][0] = (old[0] * dp[v][1] + old[0] * dp[v][0]) % MOD;
44         dp[u][1] = (old[1] * dp[v][1] + old[1] * dp[v][0] + old[0] * dp[v][1]) % MOD;
45     }
46 }
47
48 int main() {
49     ios::sync_with_stdio(false), cin.tie(0);
50     cin >> n;
51     rep(i, 1, n) {
52         int p;
53         cin >> p;
54         G[p].pb(i);
55     }
56     rep(i, 0, n) cin >> x[i];
57     dfs(0);
58     cout << dp[0][1] << endl;
59     return 0;
60 }
时间: 2024-10-13 01:04:42

Codeforces Round #263 (Div. 2) D. Appleman and Tree 树形dp的相关文章

Codeforces Round #263 (Div. 2) D. Appleman and Tree(树形DP)

题目链接 D. Appleman and Tree time limit per test :2 seconds 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 a

Codeforces Round #263 (Div.1) B. Appleman and Tree

题目地址:http://codeforces.com/contest/461/problem/B 题目大意:给一棵树.每一个点为白色或黑色.切断一些边,使得每一个连通块有且仅有一个黑点,问划分方案数. 算法讨论:TreeDP. f[x][0..1]表示x所在连通块有0/1个黑点.设y为x的儿子,则DP方程为f[x][1]=f[x][1]*f[y][0]+f[x][1]*f[y][1]+f[x][0]*f[y][1],f[x][0]=f[x][0]*f[y][0]+f[x][0]*f[y][1].

贪心 Codeforces Round #263 (Div. 2) C. Appleman and Toastman

题目传送门 1 /* 2 贪心:每次把一个丢掉,选择最小的.累加求和,重复n-1次 3 */ 4 /************************************************ 5 Author :Running_Time 6 Created Time :2015-8-1 13:20:01 7 File Name :A.cpp 8 *************************************************/ 9 10 #include <cstdio>

Codeforces Round #419 (Div. 2) E. Karen and Supermarket(树形DP)

题目链接:Codeforces Round #419 (Div. 2) E. Karen and Supermarket 题意: 有n件物品,每个物品有一个价格,和一个使用优惠券的价格,不过这个优惠券有一个限制,必须要在第x个使用后才可以使用.现在有m的钱,问最多能买多少个物品. 题解: 每个优惠券都只与一个券有关,所以根据这个关系就可以构成一棵树. 考虑树形dp,dp[i][j][k(0|1)]表示第i个节点所构成的子树中买了j个物品,使用优惠券和不使用优惠券的最少钱. 转移方程看代码详细解释

Codeforces Round #263 (Div. 1) C. Appleman and a Sheet of Paper 树状数组暴力更新

C. Appleman and a Sheet of Paper Appleman has a very big sheet of paper. This sheet has a form of rectangle with dimensions 1 × n. Your task is help Appleman with folding of such a sheet. Actually, you need to perform q queries. Each query will have

Codeforces Round #263 (Div. 1) C. Appleman and a Sheet of Paper

题目地址:http://codeforces.com/contest/461/problem/C 题目大意:见原题. 算法分析:启发式暴力,每次把短的纸带折到长的纸带中,在全局记一个rev标记.注意细节. Code: #include <cstdio> #include <algorithm> #define N 100000 using namespace std; bool rev; int n,q,beg=1,end,typ,p,l,r,bit[N+10]; inline v

Codeforces Round #263 (Div. 1) A B C

Codeforces Round #263 (Div. 1) A:贪心,排个序,然后从后往前扫一遍,计算后缀和,之后在从左往右扫一遍计算答案 B:树形DP,0表示没有1,1表示有1,0遇到0必然合并,0遇到1也必然合并,1遇到0必然合并,1遇到1,必然切断,按照这样去转移即可 C:树状数组,再利用启发式合并,开一个l,r记录当前被子左右下标,和一个flip表示是否翻转 代码: A: #include <cstdio> #include <cstring> #include <

Codeforces Round #267 (Div. 2) C. George and Job(DP)补题

Codeforces Round #267 (Div. 2) C. George and Job题目链接请点击~ The new ITone 6 has been released recently and George got really keen to buy it. Unfortunately, he didn't have enough money, so George was going to work as a programmer. Now he faced the follow

Codeforces Round #433 (Div. 1) D. Michael and Charging Stations(dp)

题目链接:Codeforces Round #433 (Div. 1) D. Michael and Charging Stations 题意: 一个人每天要加油,1种为1000,1种为2000,如果付全额,会得到10%的回扣放在卡上. 如果卡上有剩余的回扣,可以拿来抵现金.问n天最少需要花多少钱. 题解: 很直观的一个dp就是考虑dp[i][j],表示第i天卡上剩余回扣为j的最小花费. 将所有的数除以100后,j其实是小于40的,严格的说是小于30,官方题解有个证明. 因为卡上不可能积累很多的