一道简单的树形DP送给你。

A couple of years ago, a new world wide crisis started, leaving many people with economical problems. Some workers of a particular company are trying to ask for an increase in their salaries.

数年以前,人们遭受了世界范围的经济危机。于是某司工人们要求涨薪。(我百度了一下,金融危机应该降薪才对啊~)

The company has a strict hierarchy, in which each employee has exactly one direct boss, with the exception of the owner of the company that has no boss. Employees that are not bosses of any other employee are called workers. The rest of the employees and the owner are called bosses.

除了公司的拥有者之外,每个雇员都仅有一个上司,(此时一个树形的管理体系呈现在你的眼前),管理链末端的雇员叫做工人,其余的叫老板(领导)。

To ask for a salary increase, a worker should file a petition to his direct boss. Of course, each boss is encouraged to try to make their subordinates happy with their current income, making the company’s profit as high as possible. However, when at least T percent of its direct subordinates have filed a petition, that boss will be pressured and have no choice but to file a petition himself to his own direct boss. Each boss files at most 1 petition to his own direct boss, regardless on how many of his subordinates filed him a petition. A boss only accounts his direct subordinates (the ones that filed him a petition and the ones that didn’t) to calculate the pressure percentage.

工人想涨薪时需要向他的直系领导提交请愿书。当某位管理,他的直系下属至少T%都给他递请愿书的话,他就别无选择只能也向他的上司请愿。而无论他的手下递给他多少份请愿,他只要递给他的上司一份即可。

Note that a boss can have both workers and bosses as direct subordinates at the same time. Such a boss may receive petitions from both kinds of employees, and each direct subordinate, regardless of its kind, will be accounted as 1 when checking the pressure percentage.

注意有些领导可能直系下属中既有管理层又有普通工人,则一视同仁,每个人只计数为1.

When a petition file gets all the way up to the owner of the company, all salaries are increased. The workers’ union is desperately trying to make that happen, so they need to convince many workers to file a petition to their direct boss.

现在工会要动员大家请愿,使得请愿书能一直递到终极boss的手上,他就会给涨薪。

Given the company’s hierarchy and the parameter T, you have to find out the minimum number of workers that have to file a petition in order to make the owner receive a petition.

会给出T的值,你来计算最少要发动多少工人才能达到目的。

Input
There are several test cases. The input for each test case is given in exactly two lines. The first line contains two integers N and T (1 ≤ N ≤ 105 , 1 ≤ T ≤ 100), separated by a single space. N indicates the number of employees of the company (not counting the owner) and T is the parameter described above. Each of the employees is identified by an integer between 1 and N. The owner is identified by the number 0. The second line contains a list of integers separated by single spaces. The integer Bi, at position i on this list (starting from 1), indicates the identification of the direct boss of employee i (0 ≤ Bi ≤ i−1). The last test case is followed by a line containing two zeros separated by a single space.

每组数据给出两行。第一行是N和T,其中N是公司中不包括公司主在内的雇员个数,T是之前题目中的百分之T。公司雇员从1~N编号,接下来的一行按照从第一个到第N个人的顺序给出此人的上司是谁。

Output
For each test case output a single line containing a single integer with the minimum number of workers that need to file a petition in order to get the owner of the company to receive a petition.

每组测试输出一个整数代表最少需要发动的工人数目。

Sample Input
3 100

0 0 0

3 50

0 0 0

14 60

0 0 1 1 2 2 2 5 7 5 7 5 7 5

0 0

Sample Output
3

2

5

提示:前两个样例明确了题目规则,第三个样例通过作图可以想到解题策略。

思路:深搜+排序贪心。对这棵树每一层的子结构都进行贪心选取最小的那几个(具体选几个用T算一下),就可以得到根节点的值。每个工人的值是1,管理层的值是由他对下属(子结构)的选择决定的。

也没什么可说的了,代码中有更具体的注释:

C++11、30ms

 #include <bits/stdc++.h>
#define maxn 100005
using namespace std; int n, T;
vector <int> subordinate[maxn]; int dfs(int boss)
{
int person = subordinate[boss].size();
if (person == ) return ;//当这个编号的人是工人时直接返回 vector <int> temp;//储存各个子结构的值
for (int i : subordinate[boss])//遍历当前这个人的下属们
temp.push_back(dfs(i)); subordinate[boss].clear();//没用了顺手清空 sort(temp.begin(), temp.end());//排序以便之后贪心选择最少的几个 int need = (person * T - )/ + ;//注意这是一个计算最少要选几个人的技巧 int sum = ;
for (int i = ; i < need; i++) sum += temp[i];
return sum;
} int readboss()//数据量达到了十万,普通版的快速读
{
int x = , s = , c = getchar();
while (c <= ) c = getchar();
if (c == '-') s = -, c = getchar();
for (; isdigit(c); c = getchar()) x = x* + c - ;
return x * s;
} int main()
{
while (cin >> n >> T && n && T)
{
for (int i = ; i <= n; i++)//储存每个人的直系下属
subordinate[readboss()].push_back(i);
cout << dfs() << endl;
}
}

UVa12186:Another Crisis(树形DP)的更多相关文章

  1. UVA-12186 Another Crisis 树形dp

    题目链接:https://cn.vjudge.net/problem/UVA-12186 题意 给出n, T和一棵树,树上每个节点需要选择T%个直属子节点. 问根节点一共需要选择几个节点. 思路 思路 ...

  2. 【学时总结】◆学时·VIII◆ 树形DP

    ◆学时·VIII◆ 树形DP DP像猴子一样爬上了树……QwQ ◇ 算法概述 基于树的模型,由于树上没有环,满足DP的无后效性,可以充分发挥其强大统计以及计算答案的能力. 一般来说树形DP的状态定义有 ...

  3. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  4. COGS 2532. [HZOI 2016]树之美 树形dp

    可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...

  5. 【BZOJ-4726】Sabota? 树形DP

    4726: [POI2017]Sabota? Time Limit: 20 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 128  Solved ...

  6. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  7. 树形DP

    切题ing!!!!! HDU  2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...

  8. BZOJ 2286 消耗战 (虚树+树形DP)

    给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...

  9. POJ2342 树形dp

    原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...

随机推荐

  1. Tomcat之catalina.out日志分割

    可参考:http://meiling.blog.51cto.com/6220221/1911769 本人尚未验证.

  2. CSS动画硬件加速

    http://zencode.in/14.CSS%E5%8A%A8%E7%94%BB%E7%9A%84%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96.html http:// ...

  3. 最新版ADT(Build: v22.6.2)总是引用appcompat_v7的问题

    昨天在ADT Manager里更新了一些组件,结果ADT不支持.索性直接下载了最新的ADT.但是发现无论创建什么类型的应用(无论支持的最低API是多少,或者是不是用模板),都会在创建应用的同时创建一个 ...

  4. cuda 版本查阅

    查看cuda版本 cat  /usr/local/cuda/version.txt nvcc -V

  5. Win32环境下代码注入与API钩子的实现

    本文详细的介绍了在Visual Studio(以下简称VS)下实现API钩子的编程方法,阅读本文需要基础:有操作系统的基本知识(进程管理,内存管理),会在VS下编写和调试Win32应用程序和动态链接库 ...

  6. 解决向github提交代码不用输入帐号密码

    解决方案:方案一: 在你的用户目录下新建一个文本文件.git-credentials Windows:C:/Users/username Mac OS X: /Users/username Linux ...

  7. .pdm文件怎么打开

    1. 用PowerDesigner打开.pdm文件

  8. 前端学习之——js解析json数组

    ** 前端学习之——js解析json数组** 解析json数组即对JSONArray的遍历 一.对于标准的json数组如: var result=[{"flag":1," ...

  9. 2.3-2.6 HBase java API

    一.get .put.delete.scan 1.代码 package com.beifeng.senior.hadoop.hbase; import org.apache.hadoop.conf.C ...

  10. jquery操作select(option)的取值,设置和选中

    比如 <select class="selector"> <option value ="volvo">Volvo</option ...