UVa12186:Another Crisis(树形DP)
一道简单的树形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)的更多相关文章
- UVA-12186 Another Crisis 树形dp
题目链接:https://cn.vjudge.net/problem/UVA-12186 题意 给出n, T和一棵树,树上每个节点需要选择T%个直属子节点. 问根节点一共需要选择几个节点. 思路 思路 ...
- 【学时总结】◆学时·VIII◆ 树形DP
◆学时·VIII◆ 树形DP DP像猴子一样爬上了树……QwQ ◇ 算法概述 基于树的模型,由于树上没有环,满足DP的无后效性,可以充分发挥其强大统计以及计算答案的能力. 一般来说树形DP的状态定义有 ...
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
- 【BZOJ-4726】Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- 树形DP
切题ing!!!!! HDU 2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...
- BZOJ 2286 消耗战 (虚树+树形DP)
给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...
- POJ2342 树形dp
原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...
随机推荐
- [bzoj1002] [FJOI2007]轮状病毒轮状病毒(基尔霍夫矩阵)
Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子 和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下 ...
- windows server 2008 + IIS 7.5实现多用户FTP(多账号对应不同目录
在windows server 2003 + IIS 6 的时候,就已经能实现多用户FTP的功能,不过设置有写繁琐,如果站点多的话,设置账号.权限这些东西都要搞很久.Windows server 20 ...
- php封装数据库mysql, mysqli
<?php header("content-type:text/html;charset=utf-8"); class db{ //私有的静态属性 private ...
- nyoj 269 VF
VF 时间限制:1000 ms | 内存限制:65535 KB 链接:NYOJ269 原创在:点击打开链接 题意:1-1000000000之间,各位数字之和等于给定s的数的个数. 每行给出一个数s ...
- Hihocder 1639 : 图书馆 (组合数+唯一分解 求最后一位)(妙)
给定n,(n<=10^3),然后输入n的数a[i],(a[i]<=1e10),求ans=(a1+a2+a3...an)! / (a1!*a2!*a3!...an!) 的结果的最一位数. 适 ...
- oracle 左右链接
数据表的连接有: 1.内连接(自然连接): inner只有两个表相匹配的行才能在结果集中出现 2.外连接: 包括 (1)左外连接(左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接 ...
- 12306.cn网站自动登录器源代码
去年过年放假的时候写了一个12306.cn网站的自动登录器,刚好那时候放假了,所以没把源代码放出来,现在将代码发出来,由于编写得比较仓促(从放假的下午19:00左右到晚上到00:00左右),很多细节问 ...
- 洛谷P4014分配问题——网络流24题
题目:https://www.luogu.org/problemnew/show/P4014 最大/小费用最大流裸题. 代码如下: #include<iostream> #include& ...
- git add . 的时候遇到warning: LF will be replaced by CRLF inXXX 解决办法
$ git add . warning: LF will be replaced by CRLF in shop/Runtime/Cache/86bbc820c9ec1 d314a9c71cf5651 ...
- Unity4.0配置
关于Unity4.0的使用: 一 安装Unity 在程序包管理器控制台输入命令:Istall-Pckage unity.mvc安装后会在App_Start中生成UnityConfig.cs 和Unit ...