Appleman and Tree
Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices are colored white.
Consider a set consisting of k (0 ≤ k < n) edges of Appleman's tree. If Appleman deletes these edges from the tree, then it will split into (k + 1) parts. Note, that each part will be a tree with colored vertices.
Now Appleman wonders, what is the number of sets splitting the tree in such a way that each resulting part will have exactly one black vertex? Find this number modulo 1000000007 (109 + 7).
一棵树,以0节点为根节点,给定每个节点的父亲节点,以及每个点的颜色(0表示白色,1表示黑色),切断这棵树的k条边,使得树变成k+1个联通分量,保证每个联通分量有且仅有1个黑色节点。问有多少种分割方法。
Input
The first line contains an integer n (2 ≤ n ≤ 105) — the number of tree vertices.
The second line contains the description of the tree: n - 1 integers p0, p1, ..., pn - 2 (0 ≤ pi ≤ i). Where pi means that there is an edge connecting vertex (i + 1) of the tree and vertex pi. Consider tree vertices are numbered from 0 to n - 1.
The third line contains the description of the colors of the vertices: n integers x0, x1, ..., xn - 1 (xi is either 0 or 1). If xi is equal to 1, vertex iis colored black. Otherwise, vertex i is colored white.
Output
Output a single integer — the number of ways to split the tree modulo 1000000007 (109 + 7).
Examples
input
Copy
3
0 0
0 1 1
output
Copy
2
input
Copy
6
0 1 1 0 4
1 1 0 0 1 0
output
Copy
1
input
Copy
10
0 1 2 1 4 4 4 0 8
0 0 0 1 0 1 1 0 0 1
output
Copy
27
思路:
树形DP,dp[i][0/1] 表示包含第i个结点的联通块所包含的黑色块数是1是0
当儿子结点为黑色,父亲结点为黑色,必须断开,对dp[ i ] [ 1 ]有贡献你
当儿子结点为黑色,父亲结点为白色,断开则为dp[ i ][ 0 ]有贡献,不断开则为dp[ i ] [ 1 ]有贡献
当儿子结点为白色,父亲节点为黑色时,对dp[ i ][ 1 ]有贡献
当儿子结点为白色,父亲结点为白色时,对dp[ i ][ 0 ]有贡献
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
#define N 100003
#define mod 1000000007
vector<int> maps[N];
long long dp[N][2];
int flag[N];
int vis[N];
void dfs(int n)
{
if(flag[n]==1) dp[n][1]=1,dp[n][0]=0; else dp[n][1]=0,dp[n][0]=1;
for(int i=0;i<maps[n].size();++i)
{
int temp=maps[n][i];
if(vis[temp]==0)
{
vis[temp]=1;
dfs(temp);
long long t0=dp[n][0],t1=dp[n][1];
dp[n][1]=(((t0*dp[temp][1])%mod+(t1*dp[temp][0])%mod)+(t1*dp[temp][1])%mod)%mod;
dp[n][0]=((t0*dp[temp][0])%mod+(t0*dp[temp][1])%mod)%mod;
}
}
}
int main()
{
int n;
cin>>n;
for(int i=0;i<n-1;++i)
{
int x;
cin>>x;
maps[x].push_back(i+1);
maps[i+1].push_back(x);
}
for(int i=0;i<n;++i)
cin>>flag[i];
vis[0]=1;
dfs(0);
cout<<dp[0][1]<<endl;
return 0;
}