利用题目中的数据构造出来一个向下的树。然后如果是在叶子节点的话毫无疑问就得叶子节点独自承受所需要的灯笼,如果不是叶子节点的话就得是递归回去的时候带来子树挂上了多少灯笼以及最小时间花费的节点是多少。这样如果叶子节点不够挂的时候就直接去挂那个最小的时间花费即可。
#include <bits/stdc++.h> using namespace std; #define int long long const int maxn = 100000+10; struct Node{ vector<int> next; int c; int t; } node[maxn]; int ans = 0; pair<int, int> digui(int pos) { int num = 0; int mint = node[pos].t; if (node[pos].next.size()==0) { ans += node[pos].c*node[pos].t; return make_pair(node[pos].c, node[pos].t); } for (int i=0;i<node[pos].next.size();i++) { pair<int, int> pa = digui(node[pos].next[i]); num += pa.first; mint = pa.second<mint? pa.second:mint; } if (node[pos].c>num) ans += (node[pos].c-num)*mint; return make_pair(max(node[pos].c, num), mint); } signed main() { int N; int par, c, t; int root; cin>>N; //构造一颗向着子树走的树。 for (int i=1;i<=N;i++) { cin>>par>>c>>t; if (par==-1) { root = i; } else { node[par].next.push_back(i); } node[i].c = c; node[i].t = t; } digui(root); cout<<ans; return 0; }