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; }