Anniversary party
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1520
解题思路:
每个结点有两种状态,参加和不参加,用0表示不参加,1表示参加
dp[i][1]表示第i个参与者参加了,dp[i][0]表示第i个参与者没有参加。
u代表上司,v代表员工。则状态转移方程:
dp[u][0] += max (dp[v][0], dp[v][1]) :表示上司没参加,其员工可以参加可以不参加
dp[u][1] += dp[v][0] : 表示若上司参加了,其员工一定不会参加
树形dp建树:
用连接表,这是一个有向树。
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 6005;
vector<int> v[MAXN];
int f[MAXN];
int hap[MAXN];
int dp[MAXN][2];
void dfs(int root){
dp[root][1] = hap[root];
int len = v[root].size();
for(int i = 0; i < len; i++){
int tmp = v[root][i];
dfs(tmp);
dp[root][0] += max(dp[tmp][1],dp[tmp][0]);
dp[root][1] += dp[tmp][0];
}
}
int main(){
int n;
while(~scanf("%d",&n)){
for(int i = 1; i <= n; i++){
scanf("%d",&hap[i]);
v[i].clear();
f[i] = -1;//树根标记
dp[i][0] = dp[i][1] = 0;
}
int a,b;
while(scanf("%d%d",&a,&b),a+b){
f[a] = b;
v[b].push_back(a);
}
a = 1;
while(f[a] != -1)
a = f[a];//找到树根
dfs(a);
printf("%d\n",max(dp[a][1],dp[a][0]));
}
return 0;
}