树形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)); } }
相关文章推荐
- UVa 12186 Another Crisis(树形DP)
- UVA 12186 Another Crisis(树形DP)
- UVa 12186 - Another Crisis(树形DP)
- UVA-12186 Another Crisis 树形dp
- UVa - 12186 - Another Crisis ( 树形DP )
- UVA - 12186 Another Crisis (树形dp)
- Another Crisis - UVa 12186 树形dp
- UVA 12186 Another Crisis [树形dp]
- uva 12186 Another Crisis 树形dp
- 【树形DP】UVa 12186 Another Crisis
- UVA12186--- Another Crisis (树形dp)
- UVA 12186 Another Crisis(树形DP)
- UVA - 12186 Another Crisis (树形dp)
- UVA 12186 Another Crisis 树形DP
- UVA - 12186 Another Crisis (树形DP)
- UVa 12186 - Another Crisis(树形DP)
- UVA 12186 - Another Crisis(树形DP)
- UVAOJ 12186 Another Crisis (树形DP)
- UVa 12186 工人的请愿书(树形DP)
- UVa-12186 Another Crisis (dp)