题意

  • p(父亲),c(需要挂的最少装饰物个数),t(挂一个装饰物需要的时间)的形式输入每一个树上的节点。
  • 问满足每一个节点的装饰物需求最少需要多少时间

思路

  • 对于叶子节点i,他上面至少悬挂c[i]个装饰物
  • 对于其它节点j,如果他的子节点累计挂的装饰物已经大于等于c[j],则什么都不用做,如果不够的话,就给总消耗时间加上[c[j]-sum(子树悬挂装饰物总和)]*min(子节点最小悬挂时间)

注意

  • 注意树的建立,用邻接矩阵
  • 注意dfs方式,先递归到头,回溯的时候在判断是否足够

AC代码

#include<bits/stdc++.h>
using namespace std;
int p[101010],t[101010];
long long c[101010];
vector<int> tre[101010];
long long ans;
long long dfs(int idx,int fa){
    long long sum=0;//记录挂了多少个了
    //往下走
    for(auto &i:tre[idx]){
        if(i==fa) continue;
        sum+=dfs(i,idx);
        t[idx]=min(t[idx],t[i]);//更新整棵树的最小t
    }
    if(sum<c[idx]){//没挂够/到底了
        ans+=(c[idx]-sum)*t[idx];
        return c[idx];
    }
    return sum;
}
int main(){
    int n;
    scanf("%d",&n);
    int root;
    for(int i=1;i<=n;i++){
        scanf("%d%lld%d",&p[i],&c[i],&t[i]);
        if(p[i]==-1) root=i;
        else{
            tre[p[i]].push_back(i);
            tre[i].push_back(p[i]);
        }
    }
    dfs(root,-1);
    printf("%lld",ans);
    return 0;
}
···