题目链接: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 ;
}

最新文章

  1. Three.js的光源投影
  2. [原创]移动应用测试技术圈QQ群:211828629
  3. 人民币大写金额转换C#方法
  4. linux下删除文件名乱码文件
  5. [Effective JavaScript 笔记]第44条:使用null原型以防止原型污染
  6. zabbix_agent key 传递参数
  7. Java 多线程同步的五种方法
  8. Javascript的websocket的使用方法
  9. Css 使div标签下沉到页面最低部
  10. Linux(Fedora) 安装 Oracle XE Database
  11. [JLOI 2015]装备购买
  12. ActiveMQ与spring整合
  13. Servlet案例7:jsp技术及案例
  14. Xshell存在后门
  15. tp5框架成功、失败提示模板修改
  16. 安装mysql出现no compatible servers were found
  17. BASIC-7_蓝桥杯_特殊的数字
  18. RN 离线包集成后需要注意的一些问题
  19. 《TCP/IP 详解 卷1:协议》第 4 章:地址解析协议
  20. TinyOS节点间通信相关接口和组件介绍

热门文章

  1. OFDM留空中央直流子载波目的及原理
  2. 初学node node开发环境搭建 node模块化 commonJS原理
  3. 【java设计模式】-13代理模式
  4. 修改checkbox样式-1
  5. RSA加密算法c++简单实现
  6. Zookeeper系列(十一)zookeeper的Leader选举详解(核心之一)
  7. 手把手教你设置MongoDB密码
  8. 【零基础】为什么Facebook发币就不一样
  9. 使用UltraISO制作linux系统安装u盘启动盘
  10. 空指针/0/NULL