Anniversary Party
Time limit: 0.5 second
Memory limit: 8 MB
Memory limit: 8 MB
Background
The president of the Ural State University is going to make an 80'th Anniversary party. The university has a hierarchical structure of employees; that is, the supervisor relation forms a tree rooted
at the president. Employees are numbered by integer numbers in a range from 1 to N, The personnel office has ranked each employee with a conviviality rating. In order to make the party fun for all attendees, the president does not want both an employee
and his or her immediate supervisor to attend.
Problem
Your task is to make up a guest list with the maximal conviviality rating of the guests.
Input
The first line of the input contains a number N. 1 ≤ N ≤ 6000. Each of the subsequent N lines contains the conviviality rating of the corresponding employee. Conviviality
rating is an integer number in a range from –128 to 127. After that the supervisor relation tree goes. Each line of the tree specification has the form
<L> <K>
which means that the K-th employee is an immediate supervisor of L-th employee. Input is ended with the line
0 0
Output
The output should contain the maximal total rating of the guests.
Sample
input | output |
---|---|
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0 |
5 |
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define N 6010
int n;
int dp[N][2]; /**dp[i][0]表示不选择i点时,i点及其子树能选出的最大值;dp[i][1]表示选择i点时,i点及其子树能选出的最大值**/
vector<int> c[N];/**c[j][k]为j点的第k个孩子**/
int v[N]; /**用于寻找根节点**/
void TreeDp(int x) /**树形DP**/
{
for(int i=0; i<c[x].size(); i++)
{
int y=c[x][i];
TreeDp(y);
dp[x][1]+=dp[y][0]; /**当取节点x时,dp的值等于x的子树(不取x的孩子)的dp值的和+自己的欢乐值**/
dp[x][0]+=max(dp[y][0],dp[y][1]);/**当不取节点x时,dp的值等于x的所有子树(x的孩子节点取或不取)的dp值的最大值之和**/
}
}
void read()
{
int i,a,b;
scanf("%d",&n)!=EOF;
memset(dp,0,sizeof(dp));
memset(v,0,sizeof(v));
for(i=1; i<=n; ++i)
scanf("%d",&dp[i][1]);
while(scanf("%d%d",&a,&b)!=EOF)
{
if((a+b)==0)
break;
c[b].push_back(a);
v[a]=1; /**凡是有父亲节点的,都标记为1,根节点没有父亲节点,标记是0**/
}
for(i=1; i<=n; i++)
if(v[i]==0) /**找出了根节点**/
{
TreeDp(i);
break;
}
printf("%d\n",max(dp[i][0],dp[i][1]));
}
int main()
{
read();
return 0;
}