Problem Description
While studying the history of royal families, you want to know how wealthy each family is. While you have various 'net worth' figures for each individual throughout history, this is complicated by double counting caused by inheritance. One way to estimate the wealth of a family is to sum up the net worth of a set of k people such that no one in the set is an ancestor of another in the set. The wealth of the family is the maximum sum achievable over all such sets of k people. Since historical records contain only the net worth of male family members, the family tree is a simple tree in which every male has exactly one father and a non-negative number of sons. You may assume that there is one person who is an ancestor of all other family members.
 
Input
The input consists of a number of cases. Each case starts with a line containing two integers separated by a space: N (1 <= N <= 150,000), the number of people in the family, and k (1 <= k <= 300), the size of the set. The next N lines contain two non-negative integers separated by a space: the parent number and the net worth of person i (1 <= i <= N). Each person is identified by a number between 1 and N, inclusive. There is exactly one person who has no parent in the historical records, and this will be indicated with a parent number of 0. The net worths are given in millions and each family member has a net worth of at least 1 million and at most 1 billion.
 
Output
For each case, print the maximum sum (in millions) achievable over all sets of k people satisfying the constraints given above. If it is impossible to choose a set of k people without violating the constraints, print 'impossible' instead.
 
题目大意:给n个点,每个点有一个权值,要求选k个点,这k个点任意一个点不能为其他点的父节点,求最大总权值。
思路:树形DP。ex[i]代表从开始遍历到某点x及其子节点(包括x)选i个点可以得到的最大总权值,now[i]代表从开始遍历到某点x及其子节点(不包括x)选i个点可以得到的最大总权值,函数一开始的时候ex是代表遍历到x之前的选i个点可以得到的最大总权值,那么在dfs算出now之后,ex[i] = max(now[i], ex[i-1] + a)就可以保证没有选的两个点是不符合要求的。
 
 #include <cstdio>
#include <cstring> const int MAXN = ; int head[MAXN], next[MAXN], to[MAXN];
int a[MAXN];
int ecnt, n, k;
int ans[]; inline void addEdge(int u, int v) {
to[ecnt] = v;
next[ecnt] = head[u]; head[u] = ecnt++;
//printf("%d->%d\n",u,v);
} inline void init() {
memset(head, , sizeof(head));
memset(ans, , sizeof(ans));
ecnt = ;
int f;
for(int i = ; i <= n; ++i) {
scanf("%d%d", &f, &a[i]);
addEdge(f, i);
}
} inline void _max(int &a, const int &b) {
if(a < b) a = b;
} void dfs(int u, int *ex) {
int *now = new int[];
for(int i = ; i <= k; ++i) now[i] = ex[i];
for(int p = head[u]; p; p = next[p]) {
dfs(to[p], now);
}
ex[] = ;
for(int i = k; i > ; --i) {
ex[i] = now[i];
if(ex[i-] != -) {
_max(ex[i], ex[i-] + a[u]);
}
}
delete [] now;
} int main() {
while(scanf("%d%d", &n, &k) != EOF) {
init();
dfs(,ans);
if(ans[k] == -) puts("impossible");
else printf("%d\n", ans[k]);
}
return ;
}

HDU 4169 Wealthy Family(树形DP)的更多相关文章

  1. POJ 2342 &&HDU 1520 Anniversary party 树形DP 水题

    一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点) ...

  2. hdu 5452 Minimum Cut 树形dp

    Minimum Cut Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=54 ...

  3. HDU 1520 Anniversary party [树形DP]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题目大意:给出n个带权点,他们的关系可以构成一棵树,问从中选出若干个不相邻的点可能得到的最大值为 ...

  4. hdu 1520Anniversary party(简单树形dp)

    Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  5. Install Air Conditioning HDU - 4756(最小生成树+树形dp)

    Install Air Conditioning HDU - 4756 题意是要让n-1间宿舍和发电站相连 也就是连通嘛 最小生成树板子一套 但是还有个限制条件 就是其中有两个宿舍是不能连着的 要求所 ...

  6. HDU 3586 二分答案+树形DP判定

    HDU 3586 『Link』HDU 3586 『Type』二分答案+树形DP判定 ✡Problem: 给定n个敌方据点,1为司令部,其他点各有一条边相连构成一棵树,每条边都有一个权值cost表示破坏 ...

  7. HDU 3586.Information Disturbing 树形dp 叶子和根不联通的最小代价

    Information Disturbing Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/ ...

  8. HDU 5293 Annoying problem 树形dp dfs序 树状数组 lca

    Annoying problem 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 Description Coco has a tree, w ...

  9. HDU - 3586 Information Disturbing 树形dp二分答案

    HDU - 3586 Information Disturbing 题目大意:从敌人司令部(1号节点)到前线(叶子节点)的通信路径是一个树形结构,切断每条边的联系都需要花费w权值,现在需要你切断前线和 ...

随机推荐

  1. cop2000实现补码两位乘

    程序地址 机器码 反汇编语言 指令说明 ;IN 可以使用此指令在cop2000上输入数据 00 7C4B MOV A,#4BH 模拟输入X补 02 80 MOV R0,A 放入R0 03 88F9 M ...

  2. Jboot使用appassembler-maven-plugin插件生成启动脚本

    appassembler-maven-plugin介绍: 使用appassembler-maven-plugin插件可自动生成跨平台的启动脚本,可省去手工写脚本的麻烦,而且还可以生成jsw的后台运行程 ...

  3. Linux 学习第六天

    一.VIM 1.VIM编辑器 1.1.VIM工作模式 1.1.1.命令模式:复制.剪切.粘贴.搜索等等 1.1.2.输入模式:随意对文件进行内容编辑 1.1.3.末行模式(:):保存退出,编辑环境设置 ...

  4. ubuntu下安装memcached和PHP的memcache扩展

    依赖包和软件包下载地址: Libevent:https://github.com/libevent/libevent/releases/download/release-2.1.8-stable/li ...

  5. MySQL慢日志实践

    慢日志查询作用 慢日志查询的主要功能就是,记录sql语句中超过设定的时间阈值的查询语句.例如,一条查询sql语句,我们设置的阈值为1s,当这条查询语句的执行时间超过了1s,则将被写入到慢查询配置的日志 ...

  6. PHP实现长网址与短网址

    原文地址:http://www.qqdeveloper.com/detail/29/1.html 什么是长链接.短链接 顾名思义,长链接就是一个很长的链接:短链接就是一个很短的链接.长链接可以生成短链 ...

  7. 『Python基础-15』递归函数 Recursion Function

    什么是递归函数 一种计算过程,如果其中每一步都要用到前一步或前几步的结果,称为递归的.用递归过程定义的函数,称为递归函数,例如连加.连乘及阶乘等.凡是递归的函数,都是可计算的,即能行的. 递归就是一个 ...

  8. python之变量的命名规则

    变量的命名规则: 1.变量名由数字.字母和下划线组成名 2.变量名不能以数字开头 3.禁止使用python中的关键字 4.不能使用中文和拼音 5.变量名要区分大小写 6.变量名要有意义 7.推荐写法: ...

  9. C语言经典程序100例

    -------------------------------------------------------------------------------- [程序1] 题目:古典问题:有一对兔子 ...

  10. Linux C语言编程基本原理与实践

    Linux C语言编程基本原理与实践(2018-06-16 19:12:15) Linux C语言编程基本原理与实践 高效的学习带着目的性: 是什么 -> 干什么 -> 怎么用 重识C语言 ...