首页 > 代码库 > POJ 2342 - Anniversary party

POJ 2342 - Anniversary party

树形DP的水题。

状态转移方程:

设dp[i][0]为第i号人不去的情况下,以其为根的子树,最大的rating和;dp[i][1]为第i号人去的情况下,以其为根的子树,最大的rating和;

对于树上的每条边:edge[u][ (v[1]) ]……edge[u][ (v[k]) ]……,都有:

  dp[u][0]+=∑ max( dp[ (v[k]) ][1] , dp[ (v[k]) ][0] )

  dp[u][1]+=∑ dp[ (v[k]) ][0]

 

将每个人的dp[i][1]按照输入初始化后,用vector记录下一个点的所有孩子,并且找到root,最后进行DFS即可。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<vector>
 4 #include<algorithm>
 5 #define MAXN 6005
 6 using namespace std;
 7 int n,fl[MAXN],dp[MAXN][2],root;
 8 vector<int> child[MAXN];
 9 void dfs(int now)
10 {
11     int next;
12     for(int i=0;i<child[now].size();i++)
13     {
14         next=child[now][i];
15         dfs(next);
16         dp[now][0]+=max(dp[next][1],dp[next][0]);
17         dp[now][1]+=dp[next][0];
18     }
19 }
20 int main()
21 {
22     memset(fl,0,sizeof(fl));
23     
24     scanf("%d%",&n);
25     
26     for(int i=1;i<=n;i++) scanf("%d",&dp[i][1]);
27     for(int i=1;i<=n;i++)
28     {
29         int L,K;
30         scanf("%d%d",&L,&K);
31         child[K].push_back(L);
32         fl[L]=1;
33     }
34     for(int i=1;i<=n;i++) if(fl[i]==0){root=i;break;}
35     
36     dfs(root);
37     printf("%d\n",max(dp[root][0],dp[root][1]));
38 }

 

POJ 2342 - Anniversary party