Codeforces 461 B. Appleman and Tree

树形DP。。。

B. Appleman and Tree

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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).

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 to1, vertex i is 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).

Sample test(s)

input

3
0 0
0 1 1

output

2

input

6
0 1 1 0 4
1 1 0 0 1 0

output

1

input

10
0 1 2 1 4 4 4 0 8
0 0 0 1 0 1 1 0 0 1

output

27
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn=100010;
const long long int mod=1000000007LL;

int n;
struct Edge
{
	int to,next;
}edge[3*maxn];

int Adj[maxn],Size;

void init()
{
	Size=0;
	memset(Adj,-1,sizeof(Adj));
}

void Add_Edge(int u,int v)
{
	edge[Size].to=v;
	edge[Size].next=Adj[u];
	Adj[u]=Size++;
}

int c[maxn];
long long int dp[maxn][2];

void dfs(int u,int fa)
{
	dp[u][c[u]]=1;
	for(int i=Adj[u];~i;i=edge[i].next)
	{
		int v=edge[i].to;
		if(v==fa) continue;
		dfs(v,u);
		dp[u][1]=(dp[u][1]*dp[v][1]%mod+dp[u][0]*dp[v][1]%mod+dp[u][1]*dp[v][0]%mod)%mod;
		dp[u][0]=(dp[u][0]*dp[v][0]%mod+dp[u][0]*dp[v][1]%mod)%mod;
	}
}

int main()
{
	init();
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{
		int v;
		scanf("%d",&v);
		Add_Edge(i,v);
		Add_Edge(v,i);
	}
	for(int i=0;i<n;i++)
		scanf("%d",c+i);
	dfs(0,0);
	printf("%I64d\n",dp[0][1]);
	return 0;
}
时间: 2024-10-14 03:29:27

Codeforces 461 B. Appleman and Tree的相关文章

CodeForces 416 B Appleman and Tree DP

Appleman and Tree 题解: 定义dp[u][1] 为以u的子树范围内,u这个点已经和某个黑点相连的方案数. dp[u][0] 为在u的子树范围内, u这个点还未和某个黑点相连的方案数. 转移方程: 如果 u为黑点, dp[u][0] = 0, dp[u][1] = 1, 然后考虑从下面转移过来, dp[u][1] *= dp[v][0] + dp[v][1]. 也就是说, 如果 v 点为黑,则切断这个边, 如果v点为白,则不切断, 即对于v来说,每个情况,切边的情况也只有一种,

Codeforces 461B Appleman and Tree(木dp)

题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k条边,使得树变成k+1个联通分量.保证每一个联通分量有且仅有1个黑色节点.问有多少种切割方法. 解题思路:树形dp,dp[i][0]和dp[i][1]分别表示子树一下的切割方法中,i节点所在联通块不存在黑节点和已经存在一个黑节点的方案数. #include <cstdio> #include &l

Codeforces 461B Appleman and Tree(树形dp)

题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每个节点的父亲节点,以及每个点的颜色(0表示白色,1表示黑色),切断这棵树的k条边,使得树变成k+1个联通分量,保证每个联通分量有且仅有1个黑色节点.问有多少种分割方法. 解题思路:树形dp,dp[i][0]和dp[i][1]分别表示子树一下的分割方法中,i节点所在联通块不存在黑节点和已经存在一个黑节点的方案数. #include <cstdio> #include <c

Codeforces Round #263 (Div. 2) D. Appleman and Tree(树形DP)

题目链接 D. Appleman and Tree time limit per test :2 seconds memory limit per test: 256 megabytes input :standard input output:standard output Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices a

Codeforces 461B. Appleman and Tree[树形DP 方案数]

B. Appleman and Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices are color

CF461B Appleman and Tree (树DP)

CF462D Codeforces Round #263 (Div. 2) D Codeforces Round #263 (Div. 1) B B. Appleman and Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Appleman has a tree with n vertices. Some of t

Codeforces 29D Ant on the Tree 树的遍历 dfs序

题目链接:点击打开链接 题意: 给定n个节点的树 1为根 则此时叶子节点已经确定 最后一行给出叶子节点的顺序 目标: 遍历树并输出路径,要求遍历叶子节点时按照给定叶子节点的先后顺序访问. 思路: 给每个节点加一个优先级. 把最后一个叶子节点到父节点的路径上的点优先级改为1 把倒数第二个叶子节点到父节点的路径上的点优先级改为2 如此每个点就有一个优先级,每个访问儿子节点时先访问优先级大的即可 对于无解的判断:得到的欧拉序列不满足输入的叶子节点顺序即是无解. #include <cstdio> #

CF 461B Appleman and Tree 树形DP

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

codeforces 514E Darth Vader and Tree (dp+快速幂)

codeforces 514E Darth Vader and Tree (dp+快速幂) 题意: 有一棵树,每个节点有n个儿子,给出父亲到每个儿子的距离di,问离祖先距离不超过x的子孙有多少个(子孙包括祖先)对1e9+7取模. 限制: 1 <= n <= 1e5; 0 <= x <= 1e9; 1 <= di <= 100 思路: 因为di <= 100,所以可以用快速幂来处理这道题, 大概过程为:先用dp算出前100的答案,剩下的用快速幂来处理.