【题目链接】
【算法】
树形背包
注意是一棵森林
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 210 int i,n,m,tot,x; int head[MAXN],val[MAXN],f[MAXN][MAXN],size[MAXN]; struct Edge { int nxt,to; } e[MAXN]; inline void add(int x,int y) { tot++; e[tot] = (Edge){head[x],y}; head[x] = tot; } inline void dfs(int x) { int i,j,k,y; size[x] = 1; for (i = head[x]; i; i = e[i].nxt) { y = e[i].to; dfs(y); size[x] += size[y]; for (j = size[x]; j >= 2; j--) { for (k = 1; k < j; k++) { f[x][j] = max(f[x][j],f[x][k]+f[y][j-k]); } } } } int main() { while (scanf("%d%d",&n,&m) != EOF) { if (!n && !m) break; tot = 0; memset(f,0,sizeof(f)); memset(size,0,sizeof(size)); for (i = 0; i <= n; i++) head[i] = 0; for (i = 1; i <= n; i++) { scanf("%d%d",&x,&val[i]); add(x,i); f[i][1] = val[i]; } dfs(0); printf("%d ",f[0][m+1]); } return 0; }