hdoj1520(入门树形dp)
2024-10-06 21:17:53
题目链接:https://vjudge.net/problem/HDU-1520
题意:和luogu那道没有上司的舞会一样的题,给定一棵带点权的树,父结点和子结点不能同时选,问怎么选使得权值和最大,求最大值即可。
思路:最近开始肝树形dp,从入门题开始QAQ,加油!
用dp[u][0]表示结点u不选,dp[u][1]表示选,vi是结点u的子结点,那么:
dp[u][0]=sum(max(dp[vi][0],dp[vi][1]))
dp[u][1]=val[u]+sum(dp[vi][0])
一次dfs就ok了,结果为max(dp[root][0],dp[root][1]),root要自己找。
AC代码:
#include<cstdio>
#include<algorithm>
using namespace std; const int maxn=;
int n,cnt,head[maxn],val[maxn],indeg[maxn],dp[maxn][];
struct node{
int v,nex;
}edge[maxn]; void adde(int u,int v){
edge[++cnt].v=v;
edge[cnt].nex=head[u];
head[u]=cnt;
} void dfs(int u){
dp[u][]=val[u];
for(int i=head[u];i;i=edge[i].nex){
int v=edge[i].v;
dfs(v);
dp[u][]+=max(dp[v][],dp[v][]);
dp[u][]+=dp[v][];
}
} int main(){
while(~scanf("%d",&n)){
cnt=;
for(int i=;i<=n;++i){
scanf("%d",&val[i]);
head[i]=,indeg[i]=,dp[i][]=;
}
int a,b;
while(scanf("%d%d",&a,&b),a&&b){
indeg[a]=;
adde(b,a);
}
int root;
for(int i=;i<=n;++i)
if(!indeg[i]){
root=i;
break;
}
dfs(root);
printf("%d\n",max(dp[root][],dp[root][]));
}
return ;
}
最新文章
- Three.js的光源投影
- [原创]移动应用测试技术圈QQ群:211828629
- 人民币大写金额转换C#方法
- linux下删除文件名乱码文件
- [Effective JavaScript 笔记]第44条:使用null原型以防止原型污染
- zabbix_agent key 传递参数
- Java 多线程同步的五种方法
- Javascript的websocket的使用方法
- Css 使div标签下沉到页面最低部
- Linux(Fedora) 安装 Oracle XE Database
- [JLOI 2015]装备购买
- ActiveMQ与spring整合
- Servlet案例7:jsp技术及案例
- Xshell存在后门
- tp5框架成功、失败提示模板修改
- 安装mysql出现no compatible servers were found
- BASIC-7_蓝桥杯_特殊的数字
- RN 离线包集成后需要注意的一些问题
- 《TCP/IP 详解 卷1:协议》第 4 章:地址解析协议
- TinyOS节点间通信相关接口和组件介绍