中文题目不解释:
主体思路:树形DP, 记录每个点向下最多拥有的子节点的个数的最大值。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<map> using namespace std; typedef long long LL; const int INF = 1e9+7; const int maxn = 1000; const int MOD = 1e9+7; int dp[maxn][maxn];///dp[第n个结点][攻克第n个结点下面的k个城堡] = 最大值 vector<vector<int> > G; void DFS(int root,int m) { int len = G[root].size(); for(int i=0; i<len; i++) { int e = G[root][i]; if(m > 1) DFS(e, m-1); for(int j=m; j>=2; j--)///root结点选取下面j个结点 { for(int k=1; k < j; k++)/// dp[root][j] = max(dp[root][j], dp[root][j-k]+dp[e][k]); } } } int main() { int n, m; while(scanf("%d %d", &n, &m), n+m) { G.clear(); G.resize(n+5); memset(dp, 0, sizeof(dp)); for(int i=1; i<=n; i++) { int s, w; scanf("%d %d", &s, &w); G[s].push_back(i); dp[i][1] = w; } DFS(0, m+1); printf("%d ", dp[0][m+1]); } return 0; }