题目链接:hdu 1520
树形dp裸题也是第一题,tle卡了许久
树形dp就是在树上进行的动态规划过程,因为树这种数据结构本身自带状态转移的过程(父亲到子节点或子节点到父亲),所以在树上搞一手dp就很舒服。
设父节点是子节点的直接领导,dp【i】【0】代表i不出场时以i为根的子树rating最大值,dp【i】【1】则是i出场的情况。
#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<map>
#include<string.h>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
#define LL long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define sqr(a) (a)*(a)
#define lan(a,b) memset(a,b,sizeof(a))
using namespace std;
vector<int> bian[6010];
int n;
int a[6010];
int dp[6010][2];
void pin(int i)
{
dp[i][0]=0;
dp[i][1]=a[i];
// printf("i=%d\n",i);
for(int j=0;j!=bian[i].size();j++)
{
int to=bian[i][j];
pin(to);
dp[i][0]+=max(dp[to][0],dp[to][1]);
dp[i][1]+=max(0,dp[to][0]);
}
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
bian[i].clear();
lan(a,0);
lan(dp,0);
int fa[6010]={0};
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int p,q;
while(~scanf("%d%d",&p,&q))
{
if(p==0&&q==0)
break;
bian[q].push_back(p);
fa[p]=q;
}
int id;
for(int i=1;i<=n;i++)
{
if(fa[i]==0)
{
id=i;
break;
}
}
pin(id);
printf("%d\n",max(dp[id][0],dp[id][1]));
}
return 0;
}