因为在做HDU4126的时候需要使用树形dp,然而我对树形dp一点也不了解,所以做一下树形dp的题来加深其了解,
题目不说了
dp方程是 : dp[i][0] += max(dp[j][0],dp[j][1]) //i是j的父亲
dp[i][1] += dp[j][0]
其中dp[i][0] 表示该人没来
dp[i][1]表示该人来了
贴代码
#include <cstdio>
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
//常量
const int N_MAX = 6005;
//变量
int root; // 根节点
int par[N_MAX]; //爹节点,最后通过该数组找到根节点
vector<int > Ve[N_MAX];//邻接表表示树形结构
int dp[N_MAX][2];//dp[i][0] 表示i不去,dp[i][1]表示i去了
int dfs(int n)
{
for(int i=0; i<Ve[n].size();i++)
{
dfs(Ve[n][i]);
dp[n][1] += dp[Ve[n][i]][0];
dp[n][0] += max(dp[Ve[n][i]][1],dp[Ve[n][i]][0]);
}
}
int main()
{
int N;
while(scanf("%d%d", &N, &dp[1][1])!=EOF)
{
int x, y;
int res = 0;
memset(Ve,0,sizeof(Ve));
memset(par,0,sizeof(par));
if(N==0 && dp[1][1]==0)break;
for(int i=2; i<=N; i++)scanf("%d", &dp[i][1]);
for(int i=0; i<N-1; i++)
{
scanf("%d%d", &x, &y);
par[x] = y;
Ve[y].push_back(x);
}
for(int i=1; i<=N; i++)
{
if(par[i] == 0)
{
root = i;
break;
}
}
dfs(root);
res = max(dp[root][1],dp[root][0]);
printf("%d\n",res);
}
}