标签:uva 12186 another crisis 树形dp
// uva 12186 Another Crisis 树形dp // // 对于一个节点u,有k个子节点,则至少有c = (k * T - 1) / 100 + 1才能 // 发信,即c / k >= T / 100,则 c 的值为 k * T /100,上取整变成上式 // 将所有的子节点d从小到大排序,取前c个就是d[u]的值 // 紫书上的一题,之前看了好久好久,觉得挺好的,然而一直没做,今天就来 // 体验体验,挺好的一题,注意一下,如果一个节点是叶节点,直接return 1就好 // 因为此时没得选啦,必须得有.没加的,程序运行出错...应该是排序的时候吧 // 继续加油~~~练吧,dp之路还在刚刚起步啊 #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int MAX_N = 100008; vector<int> g[MAX_N]; int d[MAX_N]; bool vis[MAX_N]; int n,T; int dp(int u){ if (vis[u]) return d[u]; vis[u] = 1; if (g[u].empty()) return 1; int k = g[u].size(); vector<int> ans; for (int i=0;i<k;i++){ ans.push_back(dp(g[u][i])); } sort(ans.begin(),ans.end()); int c = (k * T - 1) / 100 + 1; int res = 0; for (int i=0;i<c;i++) res += ans[i]; return res; } void input(){ for (int i=0;i<=n;i++) g[i].clear(); int x; for (int i=1;i<=n;i++){ scanf("%d",&x); g[x].push_back(i); } memset(vis,0,sizeof(vis)); printf("%d\n",dp(0)); } int main(){ //freopen("1.txt","r",stdin); while(scanf("%d%d",&n,&T)!=EOF){ if (!n && !T) break; input(); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:uva 12186 another crisis 树形dp
原文地址:http://blog.csdn.net/timelimite/article/details/47303155