InputEmployees are numbered from 1 to N. A first line of input contains a number N. 1 <= N <= 6 000. 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 go T lines that describe a supervisor relation tree. Each line of the tree specification has the form: 
L K 
It means that the K-th employee is an immediate supervisor of the L-th employee. Input is ended with the line 
0 0OutputOutput should contain the maximal sum of guests‘ ratings. 
Sample Input
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
Sample Output
5
题意:多组输入,每组输入的第一行一个N代表N个人,接下来N行每行一个数代表如果这个人参加party的欢乐值,接下来许多行,每行两个数u,v 表示v是u的直接上属。举行一个party,如果邀请了这个人的直接上司就不能邀请这个人,要求最后总的欢乐值最大,问欢乐值最大为多少。
思路:
开一个二维dp dp[x][0]代表没有邀请x的最大欢乐值、
         dp[x][1]代表邀请了x的最大欢乐值。初始化dp[x][0]均为0 dp[x][1]为a[x]。dfs从树根遍历这棵树。具体看代码
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #include<algorithm>
 6 using namespace std;
 7 const int maxn=6010;
 8 vector<int>v[maxn];
 9 int dp[maxn][2],in[maxn],x,y;
10 int n,vis[maxn];
11 int a[maxn];
12 void dfs(int t)
13 {
14     dp[t][0]=0;        //dp数组的初始化。 
15     dp[t][1]=a[t];
16     vis[t]=1;        //vis数组的意义如同记忆化搜索,如果这个叶子节点已经同时是其他节点的叶子节点,那么它已经被访问过,dp值已经更新了,不用再往下搜,因为下面都已经被搜过了,直接拿来用就行。 
17     for(int i=0;i<v[t].size();i++)
18     {
19         int to=v[t][i];
20         if(vis[to])    //这个题数据比较水,如果不加vis数组也能过,但是时间会长。 
21             continue;
22         dfs(to);
23         dp[t][0]+=max(dp[to][0],dp[to][1]);//如果不邀请t,那么就可以邀请他的直系下属 
24         dp[t][1]+=dp[to][0];               //如果邀请t,那么久不能邀请他的直系下属 
25     }
26     return ;
27 }
28 int main()
29 {
30     while(~scanf("%d",&n))
31     {
32         for(int i=1;i<=n;i++)
33             v[i].clear();
34         memset(in,0,sizeof(in));
35         memset(dp,0,sizeof(dp));
36         for(int i=1;i<=n;i++)
37         {
38             scanf("%d",&a[i]);
39         }
40         while(~scanf("%d%d",&x,&y)&&(x+y))
41         {
42             v[y].push_back(x);
43             in[x]++;
44         }
45         memset(vis,0,sizeof(vis));
46         for(int i=1;i<=n;i++)
47         {
48             if(!in[i])
49             {
50                 dfs(i);
51                 printf("%d\n",max(dp[i][0],dp[i][1]));
52                 break;
53             }
54         }
55     }
56 }
原文:https://www.cnblogs.com/1013star/p/9941532.html