Codeforces 461B Appleman and Tree

http://codeforces.com/problemset/problem/461/B

思路:dp,dp[i][0]代表这个联通块没有黑点的方案数,dp[i][1]代表有一个黑点的方案数

转移:
首先如果儿子节点是个有黑点的,父亲节点也有黑点,那么只能分裂开,不能合并在一起,只对dp[u][1]有贡献

      如果儿子节点是个有黑点的,父亲节点没有黑点,那么可以分裂也可以合并,对dp[u][1]和dp[u][0]都有贡献

      如果儿子节点是个没有黑点的,父亲节点有黑点,那么必须和父亲合并,对dp[u][1]有贡献

      如果儿子节点是个没有黑点的,父亲节点也没黑点,那么必须和父亲合并,对dp[u][0]有贡献

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<iostream>
 6 #define ll long long
 7 const ll Mod=1000000007;
 8 ll f[200005][2];
 9 int v[200005],n,tot,go[400005],first[200005],next[400005];
10 int read(){
11     int t=0,f=1;char ch=getchar();
12     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
13     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
14     return t*f;
15 }
16 void insert(int x,int y){
17     tot++;
18     go[tot]=y;
19     next[tot]=first[x];
20     first[x]=tot;
21 }
22 void add(int x,int y){
23     insert(x,y);insert(y,x);
24 }
25 void dfs(int x,int fa){
26     if (v[x]==1) f[x][1]=1,f[x][0]=0;else f[x][1]=0,f[x][0]=1;
27     for (int i=first[x];i;i=next[i]){
28         int pur=go[i];
29         if (pur==fa) continue;
30         dfs(pur,x);
31         ll t0=f[x][0],t1=f[x][1];
32         f[x][1]=((t0*f[pur][1])%Mod+(t1*f[pur][0])%Mod)+(t1*f[pur][1])%Mod;
33         f[x][0]=((t0*f[pur][0])%Mod+(t0*f[pur][1])%Mod);
34     }
35 }
36 int main(){
37     n=read();
38     for (int i=2;i<=n;i++){
39         int x=read()+1;
40         add(x,i);
41     }
42     for (int i=1;i<=n;i++) v[i]=read();
43     dfs(1,0);
44     printf("%I64d\n",(f[1][1])%Mod);
45     return 0;
46 }

 

posted @ 2016-06-30 15:32  GFY  阅读(603)  评论(0编辑  收藏  举报