cf B. Appleman and Tree 树形DP

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;
}

猜你喜欢

转载自blog.csdn.net/qq_36921652/article/details/81477529