您的位置:首页 > 其它

【洛谷 P1352】【codevs1380】没有上司的舞会

2017-05-11 00:03 423 查看
链接:https://www.luogu.org/problem/show?pid=1352

题意:求n个点的最大带权独立集

算法:显然树形DP

* 分析:用dp[u][1]表示选第u个人时以u为根的子树的最大欢乐度,dp[u][0]表示不选第u个人时以u为根的子树的最大欢乐度。

* 又上司不能和下属同选,则有

* dp[u][1]=sigma(dp[v][0])+w[i]{v是u的儿子结点}

* dp[u][0]=sigma(max(dp[v][0],dp[v][1])){v是u的子结点}

* 边界条件:如果i是叶子,则dp[u][0]=0;dp[u][1]=w[i];

第一道树型DP,感觉要主要考虑

1.更新的时候子节点和祖先节点的关系

2.储存数据的方式

下附代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int f[10000][2],happy[10000],fa[10000];
int n;
void dfs(int x)
{
for(int i=1;i<=n;i++)
if(fa[i]==x)
{
dfs(i);
f[x][0]+=max(f[i][0],f[i][1]);
f[x][1]+=f[i][0];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&f[i][1]);
int aa,bb;
scanf("%d %d",&aa,&bb);
while(aa&&bb)
{
fa[aa]=bb;
scanf("%d%d",&aa,&bb);
}
int root=1;
while(fa[root]!=0) root=fa[root];
dfs(root);
printf("%d",max(f[root][0],f[root][1]));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: