Problem Description
There is going to be a partyto celebrate the 80-th Anniversary of the Ural State University. The Universityhas a hierarchical structure of employees. It means that the supervisorrelation forms a tree rooted at the
rector V. E. Tretyakov. In order to makethe party funny for every one, the rector does not want both an employee andhis or her immediate supervisor to be present. The personnel office hasevaluated conviviality of each employee, so everyone has some number
(rating)attached to him or her. Your task is to make a list of guests with the maximalpossible sum of guests' conviviality ratings.
Input
Employees are numbered from 1to N. A first line of input contains a number N. 1 <= N <= 6 000. Each ofthe subsequent N lines contains the conviviality rating of the correspondingemployee. 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 ofthe tree specification has the form:
L K
It means that the K-th employee is an immediate supervisor of the L-themployee. Input is ended with the line
0 0
Output
Output should contain themaximal 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排分別表示第i個人的愉悅值。接著是成員之間的關係。雖然是以0 0結束,但是這道題貌似一定形成一棵樹,不會形成森林。所以,一定是n-1排的關係。
方法:很顯然是一個樹形DP的問題。做法很多,我同學是從任意點進入進行DP的方法。不過,個人感覺自己的做法比較容易理解。先建樹,然後找到根結點,即是沒有入度的點。(用的一個vector反向儲存,其實用標記數組標記一下就OK 了,這裡當時略SB了)然後就開始DP。是否取這個點,如果取,就是f[i][1],不取就是f[i][0]。那麼,取的話,就一定是f[i][1] =
∑f[j][0]+a[i](f[j][0]表示i的子節點不取);如果取那麼就是f[i][0]=
∑max(f[j][1],f[j][0]),即是他的每個子節點取或者不取狀態的最大值相加。
#include<iostream>#include<vector>#include<cstdio>#include<cstring>#include<cstdlib>using namespace std;int f[6010][2] ,a[6010];vector<int> v[6010] ,rv[6010];void deal(int x){int i;if(v[x].size()){for(i = 0;i<v[x].size();i++){deal(v[x][i]);}}f[x][1] += a[x];f[x][0] = 0;for(i = 0;i<v[x].size();i++){f[x][1] += f[v[x][i]][0];if(f[v[x][i]][0] > f[v[x][i]][1]){f[x][0] += f[v[x][i]][0];}else{f[x][0] += f[v[x][i]][1];}}};int main(){int n ,i ,b ,c;while(scanf("%d",&n)!=EOF){for(i = 0;i<6010;i++){v[i].clear();rv[i].clear();}for(i = 1;i<=n;i++){scanf("%d",&a[i]);}while(scanf("%d%d",&c,&b)!=EOF){if(b==0&&c==0){break;}v[c].push_back(b);rv[b].push_back(c);}int num;for(i = 1;i<=n;i++){if(rv[i].empty()){num = i;break;}}memset(f,0,sizeof(f));deal(num);if(f[num][0] > f[num][1]){printf("%d\n",f[num][0]);}else{printf("%d\n",f[num][1]);}}return 0;}