码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5647 DZY Loves Connecting 树形dp

时间:2016-05-09 01:30:16      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5647

题解:

令dp[u][0]表示u所在的子树中所有的包含i的集合数,设u的儿子为vi,则易知dp[u][0]=(dp[v1][0]+1)*...*(dp[vk][0]+1)。

令dp[u][1]表示u所在的子树中所有的包含i的集合数的大小的和,则有dp[u][1]=dp[u][1]*(dp[v][0]+1)+dp[v][1]*dp[u][0];

其中dp[u][1]*(dp[v][0]+1)表示新引入v的(dp[v][0]+1)个组合的时候,左边已知的贡献值(dp[u][1],即已知的包含节点i的集合数的大小的和)增倍之后的量。

dp[v][1]*dp[u][0]则与上面刚好反过来,考虑对于已知的dp[u][0]种集合数,儿子v的贡献值增倍后的量。

则最后的答案为dp[1][1]+...+dp[n][1]

ps: 如果还不明白dp[u][0],dp[u][1]表示的含义,可以用代码跑一下简单的样例,把它们都打印出来,应该会好理解一些。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 
 6 const int maxn = 2e5 + 10;
 7 const int mod = 1e9 + 7;
 8 typedef long long LL;
 9 
10 struct Edge {
11     int v, ne;
12     Edge(int v, int ne) :v(v), ne(ne) {}
13     Edge() {}
14 }egs[maxn];
15 
16 int head[maxn], tot;
17 int n;
18 
19 void addEdge(int u, int v) {
20     egs[tot] = Edge(v, head[u]);
21     head[u] = tot++;
22 }
23 
24 LL dp[maxn][2];
25 
26 void solve(int u) {
27     dp[u][0] = dp[u][1] = 1;
28     int p = head[u];
29     while (p != -1) {
30         Edge& e = egs[p];
31         solve(e.v);
32         dp[u][1] = (dp[u][1] * (dp[e.v][0] + 1) + dp[e.v][1] * dp[u][0]) % mod;
33         dp[u][0] = dp[u][0] * (dp[e.v][0] + 1)%mod;
34         p = e.ne;
35     }
36 }
37 
38 void init() {
39     memset(head, -1, sizeof(head));
40     tot = 0;
41 }
42 
43 int main() {
44     int tc;
45     scanf("%d", &tc);
46     while (tc--) {
47         init();
48         scanf("%d", &n);
49         for (int i = 2; i <= n; i++) {
50             int v;
51             scanf("%d", &v);
52             addEdge(v, i);
53         }
54         solve(1);
55         LL ans = 0;
56         for (int i = 1; i <= n; i++) {
57             //printf("dp[%d][1]:%d\n", i,dp[i][1]);
58             ans += dp[i][1];
59             ans %= mod;
60         }
61         printf("%lld\n", ans);
62     }
63     return 0;
64 }
65 
66 /*
67 1 //testcase
68 3
69 1
70 1
71 */

 

HDU 5647 DZY Loves Connecting 树形dp

标签:

原文地址:http://www.cnblogs.com/fenice/p/5472417.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!