您的位置:首页 > 其它

树形dp uva 12186 Another Crisis

2018-01-19 11:22 585 查看

题意:

某公司里有一个老板和n(n≤10 5 )个员工组成树状结构,除了老板之外每个员工都有唯

一的直属上司。老板的编号为0,员工编号为1~n。工人们(即没有直接下属的员工)打算

签署一项请愿书递给老板,但是不能跨级递,只能递给直属上司。当一个中级员工(不是工

人的员工)的直属下属中不小于T%的人签字时,他也会签字并且递给他的直属上司。问:

要让公司老板收到请愿书,至少需要多少个工人签字?

题目分析:

设d(u)表示让u给上级发信最少需要多少个工人。假设u有k个子结点,则至少需要c=(kT-

1)/100+1个直接下属发信才行。把所有子结点的d值从小到大排序,前c个加起来即可。最终

答案是d(0)。因为要排序,算法的时间复杂度为O(nlogn)

#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;
#define N 100005
int n,T;
vector<int>v
;
int d
;

int dp(int x)
{
int k = v[x].size();
if(k == 0)return 1;
vector<int>t;
for(int i=0; i<k; i++)
{
t.push_back(dp(v[x][i]));///每个分支需要多少人dfs求解
}
sort(t.begin(),t.end());///进行排序,选择较小人数的分支
int c = (k*T-1)/100+1;///>=(T%)的人
int ans = 0;
for(int i=0; i<c; i++)///统计出前几个分支就是答案
{
ans+=t[i];
}
return ans;
}
int main()
{
while(scanf("%d%d",&n,&T),(n||T))
{
for(int i=0;i<=n;i++){
v[i].clear();
}
for(int i=1; i<=n; i++)
{
int x;
scanf("%d",&x);
v[x].push_back(i);
}
printf("%d\n",dp(0));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: