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

codeforces 酱游记

时间:2014-09-07 08:41:44      阅读:323      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   ar   strong   for   2014   

  Codeforces Round #263 Div.1:

  B. Appleman and Tree

  题目大意:给一棵树,每个点可能是黑色或白色。求有多少种方案使得这棵树被分成k份,每份有且仅有一个黑点。

  一看就知道是树形dp,可是不会做...题解思路很巧妙,很有借鉴意义。用dp[v][0]表示当前点及与它同一块的点没有黑点,dp[v][1]表示当前点及与它同一块的点有且仅有一个黑点。然后就是dp了。dp时有一个技巧:当前点为白色,而我们要求dp[v][1]时,我们必须只连接一个dp[child[i]][1]。我们可以直接用dp[v][0]来得到这时候的dp[v][1]。这样做既简洁又方便。实在是很神奇!

bubuko.com,布布扣
 1 //7697563     2014-09-07 04:12:28     moxiaomo     B - Appleman and Tree     GNU C++     Accepted     31 ms     8200 KB 
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 typedef long long LL;
 5 const int maxn=100001;
 6 const LL MOD=1000000007;
 7 
 8 int pos,lin[maxn],ta[maxn],sd[maxn];
 9 inline void biu(int s,int t) { ++pos; lin[pos]=ta[s]; ta[s]=pos; sd[pos]=t; }
10 
11 int n;
12 int color[maxn];
13 LL dp[maxn][2];
14 void dfs(int v)
15 {
16     dp[v][color[v]]=1;
17     for (int i=ta[v];i;i=lin[i])
18     {
19         dfs(sd[i]);
20         if (color[v]==1)
21         {
22             //dp[v][0]=0;
23             dp[v][1]=dp[v][1]*(dp[sd[i]][0]+dp[sd[i]][1])%MOD;
24         }
25         else
26         {
27             dp[v][1]=dp[v][1]*(dp[sd[i]][0]+dp[sd[i]][1])%MOD;
28             dp[v][1]=(dp[v][1]+dp[v][0]*dp[sd[i]][1])%MOD;
29             dp[v][0]=dp[v][0]*(dp[sd[i]][0]+dp[sd[i]][1])%MOD;//--
30         }
31     }
32 } 
33 int main()
34 {
35     scanf("%d",&n);
36     for (int i=0,p;i<n-1;i++) scanf("%d",&p),biu(p,i+1);
37     for (int i=0;i<n;i++) scanf("%d",color+i);
38     dfs(0);
39     cout<<dp[0][1]<<endl;
40 }
B. Appleman and Tree

 

codeforces 酱游记

标签:style   blog   http   color   os   ar   strong   for   2014   

原文地址:http://www.cnblogs.com/monmonde/p/3960094.html

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