传送门
根据题意,我们用两个一朵多维数组H[2][maxn]来存状态
其中H[1][i]代表邀请i的值
H[0][i]代表不邀请i的值
可得状态转移方程
H[0][k]=max(H[1][i],H[0][i])返回根节点的最大值
H[1][k]+=H[0][k]因为子节点如果不邀请,就直接邀请i
然后比较。。。
代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#define IV inline void
#define II inline int
#define RI register int
using namespace std;
II maxx(int x,int y){
return x>y?x:y;
} //再加上快读就完美了QWQ
int N,H[2][6001],fa[6001],n,root; //fa是存父亲节点的的数组
bool pd[6001]; //判断子节点有没有被遍历过
IV dfs(int k)
{
pd[k]=1;
for(RI i=1;i<=N;i++)
{
if(pd[i])
continue;//遍历过就继续
if(fa[i]==k)
{
dfs(i);
H[1][k]+=H[0][i];
H[0][k]+=maxx(H[0][i],H[1][i]);//转移操作
}
}
//如果搜不到的话,即为叶子节点或子节点搜完,函数结束
}
int main()
{
scanf("%d",&N);
for(RI i=1;i<=N;i++)
scanf("%d",&H[1][i]);
for(RI i=1;i<=N-1;i++)
{
cin>>n;
cin>>fa[n];
} //杂乱的输入操作233
for(RI i=1;i<=N;i++)
if(!fa[i]) //如果没有父亲,就为根节点
{
dfs(i);
cout<<maxx(H[0][i],H[1][i]); //最后老大还要选择观赏还是耍
break;
}
return 0;
}