【URAL1039】Anniversary Party
Anniversary Party
題目背景
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\)
題目描述
Your task is to make up a guest list with the maximal conviviality rating of the guests.
輸入格式
The first line of the input contains a number \(N\). \(1 \le N \le 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\)
輸出格式
The output should contain the maximal total rating of the guests.
樣例輸入
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0
樣例輸出
5
題解
題意:有一棵樹,每個點有一個權值,可以選擇一些點,要求一個點和它父親不能同時被選擇,求選擇的點的權值之和最大為多少。
很裸的樹上dp,我們令\(dp[i][1/0]\)表示\(i\)這個點選或不選,以\(i\)為根的子樹內權值之和最大為多少。
轉移方程就是:
\(dp[i][1]=\sum dp[j][0]\)
\(dp[i][0]=\sum max\)(\(dp[j][0],dp[j][1]\))
\(j\)為\(i\)的兒子。
上程式碼:
#include<bits/stdc++.h>
using namespace std;
int n;
int x,y;
int a[6009];
int dp[6009][2];
struct aa{
int to,nxt;
}p[20009];
int h[6009],len=1;
void add(int u,int v){
p[++len].to=v;
p[len].nxt=h[u];
h[u]=len;
}
void dfs(int u,int fa){
int sum=0,ss=0;
dp[u][0]=0;
dp[u][1]=a[u];
for(int j=h[u];j;j=p[j].nxt){
if(p[j].to!=fa){
dfs(p[j].to,u);
dp[u][0]+=max(dp[p[j].to][0],dp[p[j].to][1]);
dp[u][1]+=dp[p[j].to][0];
}
}
}
int main(){
scanf("%d",&n);
for(int j=1;j<=n;j++)
scanf("%d",&a[j]);
while(1){
scanf("%d%d",&x,&y);
if(x==0 && y==0) break;
add(x,y);
add(y,x);
}
dfs(1,0);
printf("%d",max(dp[1][0],dp[1][1]));
return 0;
}