UVA - 12186
Another Crisis
|
The question is from here.
My Solution
d(i)表示给上级发信至少需要多少工人。把所有子结点的d值排序然后取前c个,
对除非的处理 ★★ c = (k*T - 1) /100 +1;
用前向星储存树 每组数据搞完要 for 1 -> n 对sons[ i ].clear();
#include <iostream> #include <cstdio> #include <vector> #include <algorithm> using namespace std; const int maxn = 100008; int n,t,T; vector<int> sons[maxn]; //sons[i] 为结点i的子列表 int dp(int u) { if(sons[u].empty()) return 1; int k = sons[u].size(); vector<int> d; for(int i = 0; i < k; i++) d.push_back(dp(sons[u][i])); sort(d.begin(),d.end()); int c = (k*T-1) /100 +1; int ans = 0; for(int i = 0; i < c; i++) ans += d[i]; return ans; } int main() { while(scanf("%d%d", &n, &T)){ if(n == 0 && T == 0) break; for(int i = 1; i <= n; i++){ scanf("%d", &t); sons[t].push_back(i); } printf("%d\n", dp(0)); for(int i = 0; i <= n; i++){ sons[i].clear(); } } return 0; }
也可以写成这样
<span style="font-size:14px;">#include <iostream> #include <cstdio> #include <vector> #include <algorithm> //#define LOCAL using namespace std; const int maxn = 100008; int n,t,T; vector<int> sons[maxn]; //sons[i] 为结点i的子列表 void build() { for(int i = 1; i <= n; i++){ scanf("%d", &t); sons[t].push_back(i); } } int dp(int u) { if(sons[u].empty()) return 1; int k = sons[u].size(); vector<int> d; for(int i = 0; i < k; i++) d.push_back(dp(sons[u][i])); sort(d.begin(),d.end()); int c = (k*T-1) /100 +1; int ans = 0; for(int i = 0; i < c; i++) ans += d[i]; return ans; } void initial() { for(int i = 0; i <= n; i++){ //清空的时候要把大boss的也清理掉 sons[i].clear(); } } int main() { #ifdef LOCAL freopen("a.txt","r",stdin); #endif // LOCAL while(scanf("%d%d", &n, &T)){ if(n == 0 && T == 0) break; build(); printf("%d\n", dp(0)); initial(); } return 0; }</span>