POJ 2342 Anniversary party
树形DP
g[i]表示不取i节点最大快乐值,则子节点想取就取
f[i]表示取i节点最大快乐值,则子节点必不能取
警告:hdu需要多组数据,而题面里没有讲!!!!!!!!!!举报!!!!!!!坑了30分钟!!!
代码:
#include <iostream>
#include <stdio.h>
#include<memory>
#include<stack>
#include<string.h>
#include<algorithm>
using namespace std;
int n,L,K;
int f[7000],g[7000],fa[7000],a[7000];
int head[7000],to[7000],nxt[7000];
int tot;
void add(int x,int y){
nxt[++tot]=head[x];
to[tot]=y;
head[x]=tot;
}
void dp(int p){
for (int i=head[p];i;i=nxt[i]) dp(to[i]);
for (int i=head[p];i;i=nxt[i]){
f[p]+=g[to[i]];
g[p]+=max(f[to[i]],g[to[i]]);
}
}
int main()
{
while (scanf("%d",&n)!=EOF){
memset(f,0,sizeof(f));
memset(g,0,sizeof(f));
memset(fa,0,sizeof(f));
memset(a,0,sizeof(f));
memset(head,0,sizeof(f));
memset(to,0,sizeof(f));
memset(nxt,0,sizeof(f));
tot=0;
for (int i=1;i<=n;i++){
scanf("%d",&a[i]);
f[i]=a[i];
}
scanf("%d%d",&L,&K);
while (!(L==0 && (K==0))){
add(K,L);
fa[L]=1;
scanf("%d%d",&L,&K);
}
int root=1;
while (fa[root]==1) root++;
dp(root);
int ans=max(f[root],g[root]);
printf("%d\n",ans);
}
return 0;
}