vijos1706 舞会 (树形dp)

一道不知道是不是树形dp的水题。。

 

就是选了一个点不能选他的父亲和儿子。 求一个最大值

见代码

描述

Arthur公司是一个等级森严的公司,它们有着严格的上司与下属的关系,公司以总 裁为最高职位,他有若干个下属,他的下属又有若干个下属,他的下属的下属又有若干个下属……现接近年尾,公司组织团拜活动,活动中有一部分是自由舞会,公 司的每个职员都有一个搞笑值,现要你制定一套哪些人上台的方案,使得台上所有演员的搞笑值最大。当然,职员们是不会和他们的顶头上司一起上台的。

格式

输入格式

第一行一个整数N,表示这个公司总共的职员个数。

接下来一行有N个整数,由空格隔开,第i个整数表示职员i的搞笑值Ai(-1327670≤Ai≤1327670)。

接下来N-1行,每行一个1到N的整数,第i个整数表示职员i+1的顶头上司是谁,当然总裁就是职员1。

输出格式

一个整数,表示台上所有职员搞笑值之和的最大值。

样例1

样例输入1[复制]

7
1 1 1 1 1 1 1
1
1
5
1
4
4

样例输出1[复制]

5

提示

【数据范围】
保证100%的数据N≤5000

来源

URAL 由xzx改编

 
 
代码:
 1 #include <iostream>
 2 #include <vector>
 3 #include <cstdio>
 4 using namespace std;
 5 #define MAX 5000+10
 6 vector<int> son[MAX];
 7 int fun[MAX];
 8 int N;
 9 int dp[MAX][2];
10 int dfs(int i,int part)
11 {
12     int& d =dp[i][part];
13     if(d)return d;
14 
15     if( part==0)
16     {
17         for(int k=0;k<son[i].size();k++)
18         {
19             d += max(dfs( son[i][k] , 1), dfs(son[i][k],0));
20         }
21         return d ;
22     }
23     if( part == 1)
24     {
25         for(int k=0;k<son[i].size();k++)
26         {
27             d += dfs(son[i][k],0);
28         }
29         return d= d+fun[i];
30     }
31 }
32 int main()
33 {
34     scanf("%d",&N);
35     for(int i=1;i<=N;i++)
36     {
37         scanf("%d",&fun[i]);
38     }
39     for(int i=2;i<=N;i++)
40     {
41         int d;
42         scanf("%d",&d);
43         son[d].push_back(i);
44     }
45     printf("%d\n",max(dfs( 1,0),dfs(1,1)));
46     return 0;
47 }

 

posted @ 2014-02-01 22:22  doubleshik  阅读(222)  评论(0编辑  收藏  举报