标签: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]。这样做既简洁又方便。实在是很神奇!
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 }
标签:style blog http color os ar strong for 2014
原文地址:http://www.cnblogs.com/monmonde/p/3960094.html