题解 P1352 【没有上司的舞会】
树形DP
我的f[0][i]表示i不取时开心值最大是多少
f[1][i]则表示i取时开心值最大是多少
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int f[5][6000];
int n,a,b,root;
int ne[12000],po[12000],ru[12000];
void dp(int x)
{
for(int i = po[x];i;i = ne[i])
{
dp(i);
f[1][x] = max(max(f[1][x],f[0][i]+f[1][x]),f[0][i]);//这一个点选的时候转移:可以不选子节点,可以是子节点不选时最大值+自己的值,可以是只是子节点不选时的最大值
f[0][x] = max(max(f[0][x],f[1][i]+f[0][x]),max(f[1][i],f[0][i]));//这一个点不选的时候转移:可以是自己,可以是子节点也不选,可以是子节点选时+自己,可以是仅仅子节点选时最大
}
}
int main(){
scanf("%d",&n);
for(int i = 1;i <= n;i ++)
scanf("%d",&f[1][i]);
for(int i = 1;i <= n;i ++)
{
scanf("%d%d",&b,&a);
ru[b] ++;
ne[b] = po[a]; //原理与邻接表类似 只是里面存储的都是点 可手动模拟一下
po[a] = b;
}
for(int i = 1;i <= n;i ++)
if(ru[i] == 0)
{
root = i;//找树的根
break;
}
dp(root);
printf("%d",max(f[1][root],f[0][root]));
return 0;
}