解析
题目要求在满足子树装饰物数量的情况下,求花费时间的最小值,首先用邻接表存下各根节点的子节点,dfs遍历树,用一个数组吧维护每个子树的每个节点中花费时间最少的那个,dfs返回子树已有的装饰物数,若小于更节点则更新,并加入答案
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int p[N],c[N],t[N],m[N];
vector<int> s[N];
long long ans=0;
long long dfs(int x){
// if(!s[x].size()){//这一段可有可无,有的话清晰一些,表示该节点为叶节点
// m[x]=t[x];
// ans+=c[x]*t[x];
// return c[x];
// }
long long sum=0;
for(int i=0;i<s[x].size();i++){
sum+=dfs(s[x][i]);//先自上往下遍历
m[x]=min(m[x],m[s[x][i]]);//再自下往上统计每个子树的最小花费节点
}
if(sum<c[x]) ans+=m[x]*(c[x]-sum),sum=c[x];
return sum;
}
int main(){
int n;cin>>n;
for(int i=1;i<=n;i++){
scanf("%d %d %d",&p[i],&c[i],&t[i]);
m[i]=t[i];
if(p[i]!=-1) s[p[i]].push_back(i);//存图
}
dfs(1);
cout<<ans<<endl;
return 0;
}