题意:
给出一棵以0为根的树,求含M+1个节点的以0为根的树的最大价值。
思路:
dp[i][j] 代表 以节点 i 为根的树 包含 j 个节点时的最大价值。
构造 当前节点和子节点之间的转换。
dp[u][j] = dp[son][k] + dp[u][j-k];
初始化,dp[node][1]=val[node];
而且你转移的时候要保证dp值有意义啊,所以初始化dp值都是-1;
Code:
//#include <bits/stdc++.h>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long LL;
//#pragma comment(linker, "/STACK:102400000,102400000")
const int N=2e2+10;
struct Edge{
int v;
int next;
}edge[N<<1];
int tol,head[N];
int val[N],n,m;
void init(){
tol=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v){
edge[tol].v=v;
edge[tol].next=head[u];
head[u]=tol++;
}
bool vis[N];
int dp[N][N];
void DFS(int u)
{
int v;
dp[u][1]=val[u];
for(int i=head[u];~i;i=edge[i].next){
v=edge[i].v;
if(vis[v]) continue;
vis[v]=true;
DFS(v);
for(int j=m;j>=1;j--){
for(int k=1;k<=j;k++){
if(dp[u][j-k]!=-1 && dp[v][k]!=-1)
dp[u][j]=max(dp[u][j],dp[v][k]+dp[u][j-k]);
}
}
}
}
int main(){
int u,v;
while(scanf("%d%d",&n,&m)){
if(!n && !m) break;
m++;
init();
val[0]=0;
for(v=1;v<=n;v++){
scanf("%d%d",&u,&val[v]);
add(u,v);
add(v,u);
}
memset(dp,-1,sizeof(dp));
memset(vis,false,sizeof(vis));
vis[0]=true;
DFS(0);
printf("%d\n",dp[0][m]);
}
return 0;
}