Description

有一颗N个节点的树,其中1号节点是整棵树的根节点,而对于第ii个点(2≤i≤N)(2≤i≤N),其父节点为PiPi

对于这棵树上每一个节点Snuke将会钦定一种颜色(黑或白),以及一个非负整数的点权。

Snuke有一个他最喜欢的整数序列,X1,X2,...,XNX1,X2,...,XN,他希望能够钦定这些点的点权和颜色。使得:

对于每一个点ii,都满足ii的整颗子数内所有和ii颜色相同的点(包括ii本身)的点权和恰好为XiXi。

现在给定你这棵树的结构和Snuke最喜欢的整数序列,请你判断是否有一种钦定的方案使得其满足上文所述的条件

Input

第一行一个正整数NN表示点的数量。

第二行N−1N−1个正整数,其中第ii个数表示编号为i+1i+1的点的父节点编号。

第三行NN个非负整数,表示Snuke最喜欢的整数序列。

Output

如果存在一种可行方案,则输出"POSSIBLE";

否则,输出"IMPOSSIBLE"

(不加引号)

Sample Input

  1. Sample 1
  2. 3
  3. 1 1
  4. 4 3 2
  5. Sample 2
  6. 3
  7. 1 2
  8. 1 2 3
  9. Sample 3
  10. 8
  11. 1 1 1 3 4 5 5
  12. 4 1 6 2 2 1 3 3
  13. Sample 4
  14. 1
  15. 0

Sample Output

  1. Sample 1
  2. POSSIBLE
  3. Sample 2
  4. IMPOSSIBLE
  5. Sample 3
  6. POSSIBLE
  7. Sample 4
  8. POSSIBLE

HINT

1≤N≤10001≤N≤1000

1≤Pi≤i−11≤Pi≤i−1

0≤Xi≤5000

Sol

首先我们发现,一个点的子树中的和只要小于等于\(w[x]\)即可,因为\(val[x]\)可以是任意非负整数,但是另外一种颜色的值要尽量小,这样对它的祖先节点的贡献会更大。所以我们用\(f[x]\)表示x点子树中另一种颜色的最小值。

然后我们对于它的每个子节点做一次背包,子节点的权值要么是\(w[son]\),要么是\(f[son]\),而这两个值恰好一个给\(f[x]\)做贡献,一个给\(w[x]\)做贡献,这就是一个裸的背包了,用这两个式子结合转移即可,之后我们在\(0-w[i]\)中找到最小值并作为\(f[x]\)的值即可。如果全都是inf说明这个点找不到合适的取值,就return 0。

最后只需要判断dfs(1)的返回值即可。

Code

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int n,x,v[1005],f[1005],g[2][5005];vector<int>e[1005];
  4. bool dfs(int x)
  5. {
  6. if(!e[x].size()){f[x]=0;return 1;}
  7. for(int i=0;i<e[x].size();i++) if(!dfs(e[x][i])) return 0;
  8. int w=1;memset(g[w],0x3f,sizeof(g[w]));g[w][0]=0;
  9. for(int i=0;i<e[x].size();i++)
  10. {
  11. w=!w;memset(g[w],0x3f,sizeof(g[w]));
  12. for(int j=0;j<=v[x];j++)
  13. {
  14. if(j>=f[e[x][i]]) g[w][j]=min(g[w][j],g[w^1][j-f[e[x][i]]]+v[e[x][i]]);
  15. if(j>=v[e[x][i]]) g[w][j]=min(g[w][j],g[w^1][j-v[e[x][i]]]+f[e[x][i]]);
  16. }
  17. }
  18. int gg=2147483647;
  19. for(int i=0;i<=v[x];i++) gg=min(gg,g[w][i]);
  20. if(gg>1e9) return 0;f[x]=gg;return 1;
  21. }
  22. int main()
  23. {
  24. scanf("%d",&n);
  25. for(int i=2;i<=n;i++) scanf("%d",&x),e[x].push_back(i);
  26. for(int i=1;i<=n;i++) scanf("%d",&v[i]);
  27. if(dfs(1)) puts("POSSIBLE");else puts("IMPOSSIBLE");
  28. }

【ARC083E】Bichrome Tree 树形dp的更多相关文章

  1. 熟练剖分(tree) 树形DP

    熟练剖分(tree) 树形DP 题目描述 题目传送门 分析 我们设\(f[i][j]\)为以\(i\)为根节点的子树中最坏时间复杂度小于等于\(j\)的概率 设\(g[i][j]\)为当前扫到的以\( ...

  2. hdu-5834 Magic boy Bi Luo with his excited tree(树形dp)

    题目链接: Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: ...

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

  4. codeforces 161D Distance in Tree 树形dp

    题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...

  5. hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。

    /** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...

  6. 5.10 省选模拟赛 tree 树形dp 逆元

    LINK:tree 整场比赛看起来最不可做 确是最简单的题目. 感觉很难写 不过单独考虑某个点 容易想到树形dp的状态. 设f[x]表示以x为根的子树内有黑边的方案数. 白边方案只有一种所以不用记录. ...

  7. Codeforces Round #263 Div.1 B Appleman and Tree --树形DP【转】

    题意:给了一棵树以及每个节点的颜色,1代表黑,0代表白,求将这棵树拆成k棵树,使得每棵树恰好有一个黑色节点的方法数 解法:树形DP问题.定义: dp[u][0]表示以u为根的子树对父亲的贡献为0 dp ...

  8. codeforces Round #263(div2) D. Appleman and Tree 树形dp

    题意: 给出一棵树,每个节点都被标记了黑或白色,要求把这棵树的其中k条变切换,划分成k+1棵子树,每颗子树必须有1个黑色节点,求有多少种划分方法. 题解: 树形dp dp[x][0]表示是以x为根的树 ...

  9. POJ 2486 Apple Tree(树形DP)

    题目链接 树形DP很弱啊,开始看题,觉得貌似挺简单的,然后发现貌似还可以往回走...然后就不知道怎么做了... 看看了题解http://www.cnblogs.com/wuyiqi/archive/2 ...

随机推荐

  1. composer 的设计原理及其基本用法

    相信有在用PHP的朋友近年来常听到composer这个套件管理工具.它到底是做什么用的?又是为了解决什么问题而存在呢? 要了解这个,得先从历史开始说起…. PHP最早加载类的方法 初学PHP时,最早会 ...

  2. 清除stoped impdp/expdp job的方法

    stoped impdp/expdp job会在dba_datapump_jobs中留下一条记录,显示为not running. 清除stopped job分两种情况: 1) job能够attach ...

  3. 基于Halcon的一维条码识别技巧

    Bar Code 条形码 1.clear_all_bar_code_models    清除所有条形码模型释放内存clear_all_bar_code_models( : : : )2.clear_b ...

  4. 微信公众号php从0开发,包括功能(自定义菜单,分享)

    之前写的一篇微信公众号文章. 工作需要,进行此次调研,并记录开发过程. 开发目的,页面授权,页面获取用户头像,用户昵称 微信id, 分享页面. 微信订阅号 无法获取用户个人信息 写在记录前,公众号也是 ...

  5. angularJS笔记之过滤器

    angular的过滤器用法: 1.模板中使用 {{expression|filter}} 也可以多个filter连用 {{expression|filter1|filter2|...}} filter ...

  6. 【290】Python 常用说明

    1. 双击直接运行 python 代码暂停显示的方法:python学习笔记(3)--IDLE双击运行后暂停 需要添加如下代码: import os os.system("pause" ...

  7. webmagic使用

    webmagic是Java语言用于爬虫的工具.官网地址:http://webmagic.io/,中文文档地址:http://webmagic.io/docs/zh/ 使用webmagic有3种配置需要 ...

  8. oracle数据库导入导出数据

    导出命令 exp username/password@192.168.x.xx/orcl file='D:\20170126.dmp' log='D:\20170126.log' 导入命令 imp u ...

  9. 为什么要有http响应码

    其实还是比较容易理解的.这就和你去小卖部买东西一样,老板,我想要一袋大米,那老板先得回答有还是没有,还是说我们这没有,去其它地方买去吧,得先给个说法,这个说法就是http相应码,有了http响应码之后 ...

  10. anacondas 下 安装xgboost & keras

    mac : 安装anaconda, cd到anaconda 目录下 pip install xgboost 测试: 在当前的¥ python , 进入python 环境 import xgboost ...