• hihocoder 1500 EL SUENO


    树上背包。

    简单的树形$dp$,计算出摧毁每一个节点所需的最小费用,背包即可。

    #include<bits/stdc++.h>
    using namespace std;
    
    struct X
    {
        int fa;
        int in;
        int ip;
        int c;
    }s[2010];
    
    int dp[2010][20010];
    int cost[2010];
    int f[20010];
    
    vector<int>g[2010];
    int n,root,ans;
    
    void dfs(int x)
    {
        if(g[x].size()==0)
        {
            cost[x]=s[x].c;
            return ;
        }
    
        for(int i=0;i<g[x].size();i++)
        {
            int to=g[x][i];
            dfs(to);
        }
        for(int j=1;j<=s[x].in;j++) f[j]=dp[x][j]=0x7FFFFFFF;
    
        for(int i=0;i<g[x].size();i++)
        {
            int A = cost[g[x][i]],B = s[g[x][i]].ip;
            if(A==0x7FFFFFFF) continue;
    
            for(int j=1;j<=s[x].in;j++) f[j]=0x7FFFFFFF;
            for(int j=0;j<=s[x].in;j++)
            {
                if(dp[x][j]==0x7FFFFFFF) continue;
                f[min(s[x].in,j+B)] = min(f[min(s[x].in,j+B)],dp[x][j] + A);
            }
            for(int j=0;j<=s[x].in;j++) dp[x][j] = min(dp[x][j],f[j]);
        }
        cost[x] = dp[x][s[x].in];
        if(cost[x]!=0x7FFFFFFF) cost[x] = cost[x] + s[x].c;
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d%d%d",&s[i].fa,&s[i].in,&s[i].ip,&s[i].c);
            if(s[i].fa==0) root=i;
            g[s[i].fa].push_back(i);
        }
    
        ans=0x7FFFFFFF;
        dfs(root);
        ans=cost[root];
    
        if(ans!=0x7FFFFFFF) printf("%d
    ",ans);
        else printf("-1
    ");
    
        return 0;
    }
  • 相关阅读:
    20210123
    20210122
    20210121
    20210120
    2020119
    20210118
    20210117
    20210116
    例2-8
    例2-6
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6683156.html
Copyright © 2020-2023  润新知