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 }