【树形DP】洛谷P1352 没有上司的舞会

链接

https://www.luogu.org/problemnew/show/P1352


大意

给定一棵树,选了儿子就不能选爸爸,求最大价值


思路

树形 dp d p

f[x] f [ x ] 表示选 x x 点的最大价值

g[x] g [ x ] 表示不选 x x 点的最大价值

显然,选该点,我们就不能选其儿子,得到方程

f[x]=yson[x]g[y] f [ x ] = ∑ y ∈ s o n [ x ] g [ y ]

然后,不选该点,我们可以选其儿子,也可以不选,得到方程

g[x]=yson[x]max{f[y],g[y]} g [ x ] = ∑ y ∈ s o n [ x ] m a x { f [ y ] , g [ y ] }

找到根节点进行 dp d p 即可


代码

#include
#include
#include
using namespace std;
int g[10001],f[10001],a[10001],root,n;
vector<int>son[10001];
bool rd[10001];
inline void dfs(register int x)
{
    g[x]=0;f[x]=a[x];
    for(register int i=0;iint y=son[x][i];
        dfs(y);
        g[x]+=max(f[y],g[y]);
        f[x]+=g[y];
    }
}
signed main()
{
    scanf("%d",&n);
    for(register int i=1;i<=n;i++) scanf("%d",a+i);
    for(register int i=1,x,y;iscanf("%d %d",&x,&y),rd[x]=1,son[y].push_back(x);
    for(register int i=1;i<=n;i++) if(!rd[i]) root=i;//找到根节点
    dfs(root);
    printf("%d",max(f[root],g[root]));//输出
}

你可能感兴趣的:(dp)