自己理解
2025-07-18 16:02:32
发布于:浙江
2阅读
0回复
0点赞
#include <cstdio>
#include <cctype>
#include <algorithm>
#define maxn 105
inline int read() {
    int d=0;char ch=getchar();while(!isdigit(ch))ch=getchar();
    while(isdigit(ch)){d=d*10+ch-48;ch=getchar();}return d;
}
int n, k;
int w[maxn], v[maxn], d[maxn];
int head[maxn], ver[maxn], nxt[maxn], tot;
inline void add(int u, int v) {
    ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;
}
int dep[maxn]; // 每个节点的深度
int f[maxn][maxn][maxn], g[maxn][maxn][maxn];
int stk[maxn], tots; // 为了方便转移,我们用一个栈维护u的祖先
void dfs(int u) {
    stk[++tots] = u;
    for(int p = head[u]; p; p = nxt[p]) {
        int v = ver[p];
        dep[v] = dep[u]+d[v], dfs(v);
        // 先向下递归,算出子树的答案
        // 当前要统计的子树为v
        for(int i = 1; i <= tots; ++i) { // 枚举祖先
            for(int j = k; j >= 0; --j) { // 这里j的顺序不能反,因为我们是拿之前的状态去更新新的状态
                f[u][stk[i]][j] += f[v][stk[i]][0];
                g[u][stk[i]][j] += f[v][u][0];
                // 注意在增加一棵子树的时候,状态表示的范围扩大了
                // 所以必须先将一个状态拿出来先更新,否则f和g表示的答案不包括当前子树
                for(int l = 1; l <= j; ++l) {
                    // 当前子树v总共建了l个伐木场,此时u前面的子树建了j-l个伐木场
                    
                    // u不建伐木场,此时子树中未被处理的木料要全部运往stk[i]
                    f[u][stk[i]][j] = std::min(f[u][stk[i]][j], f[v][stk[i]][l]+f[u][stk[i]][j-l]);
                    
                    // u建伐木场,子树中未被处理的木料需要运往u
                    g[u][stk[i]][j] = std::min(g[u][stk[i]][j], f[v][u][l]+g[u][stk[i]][j-l]);
                }
            }
        }
    }
    
    // 统计点u的贡献,更新最终答案
    for(int i = 1; i <= tots; ++i) {
        for(int j = k; j >= 1; --j)
            f[u][stk[i]][j] = std::min(f[u][stk[i]][j]+w[u]*(dep[u]-dep[stk[i]]), g[u][stk[i]][j-1]);
        f[u][stk[i]][0] += w[u]*(dep[u]-dep[stk[i]]);
        // 要把u中的木料运到stk[i],需要花费w[u]*(dep[u]-dep[stk[i]])
        // 我们不需要考虑u子树的花费,因为它们已经在之前被算过了
    }
    --tots;
}
int main() {
    n = read(), k = read();
    for(int i = 1; i <= n; ++i) {
        w[i] = read(), v[i] = read(), d[i] = read();
        add(v[i], i);
    }
    dfs(0);
    printf(~~~~~~);
    return 0;      
}
全部评论 1
- 给我点赞 - 2025-07-18 来自 浙江 0






有帮助,赞一个