首先分析题目,这是一道树形dp的题目,是树形背包类的问题,以为每门课的先修课只有一门,所以这一定可以
构成一个森林结构,于是我们可以设计一个虚拟的根节点作为森林的根。
状态转移方程如下
dp[v][k]=dp[u][k]+val
dp[u][k]=max(dp[u][k],dp[v][k−1])
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 struct edge 5 { 6 int next; 7 int to; 8 }g[10005]; 9 int n,m,num; 10 int last[10005]; 11 int f[10005]; 12 int dp[1005][1005]; 13 int val[10005]; 14 int aa; 15 int a[10005]; 16 void dfs(int u,int t) 17 { 18 if(t==0) return; 19 for(int i=last[u];i;i=g[i].next) 20 { 21 int v=g[i].to; 22 for(int k=0;k<=t;k++) 23 dp[v][k]=dp[u][k]+val[v]; 24 dfs(v,t-1); 25 for(int k=1;k<=t;k++) 26 dp[u][k]=max(dp[u][k],dp[v][k-1]); 27 } 28 } 29 void add(int from,int to) 30 { 31 g[++num].next=last[from]; 32 g[num].to=to; 33 last[from]=num; 34 } 35 int main() 36 { 37 cin>>n>>m; 38 for(int i=1;i<=n;i++) 39 { 40 scanf("%d%d",&aa,&val[i]); 41 if(aa) 42 add(aa,i); 43 else 44 add(0,i); 45 } 46 dfs(0,m); 47 cout<<dp[0][m]; 48 return 0; 49 }