题目链接
题目思路
首先这个题目和背包有点类似可以选也可以不选,但是如果选了自己,自己的直系下属就不能选了。很容易想到dp。还有这题明显
和并查集的操作有点像,需要建树。但是我还是不知道怎么做 看了题解之后,明白了树形dp,其是就是dfs+dp。因为是树所以
可以想到dfs,还有这题和自己有没有被选上的状态有关,所以设置二维数组更好。而且从题目中可以看出每个人的下属可能不止一个,
所以要用二维数组,而下属个数又不确定,这时候vector的功能就出来了。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=6e4+10;
int n,i,val[maxn],x,y,prime[maxn],happy[maxn][2];
vector<int> son[maxn];
void dp(int root)
{
happy[root][0]=0;
happy[root][1]=val[root];
for(int i=0;i<son[root].size();i++)
{
dp(son[root][i]);
happy[root][0]+=max(happy[son[root][i]][0],happy[son[root][i]][1]);
happy[root][1]+=happy[son[root][i]][0];
}
return ;
}
int main()
{
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d",&val[i]);
}
for(i=1;i<=n;i++)
{
scanf("%d %d",&x,&y);
son[y].push_back(x);
prime[x]=1;
}
for(i=1;i<=n;i++)
{
if(!prime[i])
{
dp(i);
break;
}
}
int ans=max(happy[i][0],happy[i][1]);
printf("%d",ans);
return 0;
}