洛谷P2014 选课

首先分析题目,这是一道树形dp的题目,是树形背包类的问题,以为每门课的先修课只有一门,所以这一定可以

构成一个森林结构,于是我们可以设计一个虚拟的根节点作为森林的根。

状态转移方程如下

dp[v][k]=dp[u][k]+val

dp[u][k]=max(dp[u][k],dp[v][k1])

 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 }

 

posted @ 2018-10-21 19:02  snowy2002  阅读(272)  评论(0编辑  收藏  举报