【51Nod1500】苹果曼和树
来源:互联网 发布:淘宝美工助理工作内容 编辑:程序博客网 时间:2024/06/15 18:16
苹果曼有一棵n个点的树。有一些(至少一个)结点被标记为黑色,有一些结点被标记为白色。
现在考虑一个包含k(0 ≤ k < n)条树边的集合。如果苹果曼删除这些边,那么会将这个树分成(k+1)个部分。每个部分还是一棵树。
现在苹果曼想知道有多少种边的集合,可以使得删除之后每一个部分恰好包含一个黑色结点。答案对1000000007 取余即可。
Input
单组测试数据。
第一行有一个整数n (2 ≤ n ≤ 10^5),表示树中结点的数目。
第二行有n-1个整数p[0],p[1],…,p[n-2] (0 ≤ p[i] ≤ i)。表示p[i]和(i+1)之间有一条边。结点从0开始编号。
第三行给出每个结点的颜色,包含n个整数x[0],x[1],…,x[n-1] (x[i]是0或者1)。如果x[i]是1,那么第i个点就是黑色的,否则是白色的。
Output
输出答案占一行。
Input示例
3
0 0
0 1 1
Output示例
2
题解
f[u]表示u子树有一个黑点的方案数
g[u]表示u子树没有黑点的方案数
f[u]=f[u]*g[son]+f[u]*f[son]+g[u]*f[son]
g[u]=g[u]*g[son]+g[u]*f[son]
代码
#include<bits/stdc++.h>#define mod 1000000007#define inf 10000000#define N 100015#define pa pair<long long,int>typedef long long ll;using namespace std;inline int read(){ int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f;}vector<int>l[100005];int c[N],n;ll f[N],g[N];void dfs(int u,int pre){ if (c[u]) f[u]=1; else g[u]=1; for (int i=0;i<l[u].size();i++) { int v=l[u][i]; if (v==pre) continue; dfs(v,u); f[u]=(f[u]*g[v]+f[u]*f[v]+g[u]*f[v])%mod; g[u]=(g[u]*g[v]+g[u]*f[v])%mod; }}int main(){ n=read(); for (int i=0;i<n-1;i++) { int x=read(); l[x].push_back(i+1); l[i+1].push_back(x); } for (int i=0;i<n;i++) c[i]=read(); dfs(0,-1); printf("%lld",f[0]); return 0;}
阅读全文
0 0
- 【51Nod1500】苹果曼和树
- [树形DP] 51Nod1500 苹果曼和树
- 51Nod-1500-苹果曼和树
- 51 nod 苹果曼和树
- 51nod 苹果曼和树 (树形dp)
- 51nod 1500 苹果曼和树(树形dp)
- 51 nod 1500 苹果曼和树(树形DP)
- 【树形DP】51Nod 1500 苹果曼和树
- 51nod 1500 苹果曼和树【树形DP】
- 51nod 1500 苹果曼和树 树形DP
- [树形DP]51 Nod 1500——苹果曼和树
- 关于苹果和微软
- 苹果、鸡蛋和酸奶
- 苹果和虫子
- 苹果和虫子2
- 黑苹果和影片
- 15:苹果和虫子
- 苹果和虫子
- ubuntu 的ls 命令 的使用
- 二分图匹配 判断是否为二分图 —— 模板
- C++笔记——构造函数和析构函数
- OpenCV3_C++_Erode()图像的收缩 实例
- 完成一个学生管理程序,使用学号作为键添加5个学生对象,并可以将全部信息保存在文件中,可以实现对学生信息的学号查找,输出全部学生信息的功能。
- 【51Nod1500】苹果曼和树
- 事件
- 数据结构实验之栈与队列十一:refresh的停车场
- 友元
- OpenCV3_C++_Add()图像叠加 实例
- java实现简易计算器
- Liunx第一章课后习题(问答题)
- 记录微信分享回调成功后广播“”单对多“”导致安卓7.0奔溃
- 160. Intersection of Two Linked Lists