其他分享
首页 > 其他分享> > P2014 [CTSC1997] 选课 -树形dp

P2014 [CTSC1997] 选课 -树形dp

作者:互联网

 

 

 

 

#include <bits/stdc++.h>

#define debug(x) std::cerr << "[" << __LINE__ << "]: " << #x << " = " << x << "\n"

using i64 = long long;

const int N = 300 + 5;
int dp[N][N];

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n, m;
    std::cin >> n >> m;
    ++m;//增加一个选择0的点
    std::vector<std::vector<int>> adj(n + 1);
    for (int i = 1; i <= n; i++) {
        int v;
        std::cin >> v >> dp[i][1];//dp[i][j]表示对于选择的i节点的最大重量为j(自己以及选择的子节点个数)所产生的最大价值
        adj[v].push_back(i);//建有向边
    }
    std::function<void(int)> dfs = [&] (int u) {
        for (auto v : adj[u]) {
            dfs(v);//先向下
        }
        for (auto v : adj[u]) {
            for (int j = m; j > 0; --j) {//完全背包,倒着更新,本来状态方程是dp[u][i][j]
                                        //也就是对于节点u前i个子节点限重为j的最大和,状态压缩成二维
                for (int k = 0; k < j; ++k) { 
                    dp[u][j] = std::max(dp[u][j], dp[u][j - k] + dp[v][k]);
                }
            }
        }
    };
    dfs(0);
    std::cout << dp[0][m];//输出:0号节点重量为m的最大值
    return 0;
}

 

标签:std,CTSC1997,选课,P2014,dfs,int,adj,节点,dp
来源: https://www.cnblogs.com/zrzsblog/p/16574133.html