当前位置: 首页 > news >正文

树形DP题目

知识详解

核心思想:在树上做DP=DFS+状态转移

通常以节点为状态,父结节点的值依赖于子节点的值

使用后序遍历(先处理孩子,在处理父亲)

基本框架

经典问题

例题

#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 100005 typedef long long ll; const ll INF=1e18; //邻接表存储图 typedef struct AdjNode { int v;//邻居节点编号 struct AdjNode *next;//下一个邻居 }AdjNode; typedef struct AdjList { AdjNode *head;//链表头指针 }AdjList; AdjList graph[MAX];//图的邻接表数组 ll val[MAX]; ll dp[MAX]; ll maxsum=0; void add(int u,int v) { AdjNode *newnode=(AdjNode*)malloc(sizeof(AdjNode)); newnode->v=v; newnode->next=graph[u].head; graph[u].head=newnode; newnode=(AdjNode*)malloc(sizeof(AdjNode)); newnode->v=u; newnode->next=graph[v].head; graph[v].head=newnode; } void dfs(int u,int parent) { dp[u]=val[u];//初始化为节点自己的权值 AdjNode *p=graph[u].head; while(p!=NULL) { int v=p->v; if(v!=parent)//避免回到父节点 { dfs(v,u);//先递归处理字节点 if(dp[v]>0)//如果子节点的贡献为正 { dp[u]+=dp[v];//就累加到当前节点 } } p=p->next; } if(dp[u]>maxsum) maxsum=dp[u];//更新全局最大值 } void free_graph(int n) { for(int i=1;i<=n;i++) { AdjNode *p=graph[i].head; while(p!=NULL) { AdjNode *t=p; p=p->next; free(t); } graph[i].head=NULL; } } int main(int argc, char *argv[]) { int n; scanf("%d",&n); memset(graph,0,sizeof(graph)); for(int i=1;i<=n;i++) { scanf("%lld",&val[i]); } for(int i=0;i<n-1;i++) { int u,v; scanf("%d %d",&u,&v); add(u,v); } dfs(1,-1); printf("%lld",maxsum); free_graph(n); return 0; }

#include <stdio.h> #include <string.h> #include <stdlib.h> #define MAX 100010 int head[MAX],e[MAX],next[MAX],idx; //head[u]存储节点u的第一条边的索引(头指针) //e[i]存储第i条边的目标节点 //next[i]存储第i条边的下一条边的索引 //idx边的计数器,每添加一条边就+1 void add(int a,int b) { e[idx]=b;//这条边指向b next[idx]=head[a];//新边的next指向原来的第一条边 head[a]=idx++;//更新头指针为当前边,并让idx自增 } int dfs(int u) { int hmax=0,cnt=0; for(int i=head[u];i!=-1;i=next[i]) { int j=e[i]; int child_depth=dfs(j); if(child_depth>hmax) hmax=child_depth; cnt++; } return hmax+cnt; } int main() { int n; scanf("%d",&n); memset(head,-1,sizeof(head)); idx=0; for(int i=2;i<=n;i++) { int p; scanf("%d",&p); add(p,i); } printf("%d",dfs(1)); return 0; }

#include <stdio.h> #include <stdlib.h> #define MAX 100010 typedef long long ll; int n; int head[MAX],to[MAX],next_edge[MAX],weight[MAX],edge_cnt; ll dist[MAX]; int farthest_node; ll max_dist; void add_edge(int u,int v,int w) { to[edge_cnt]=v; weight[edge_cnt]=w; next_edge[edge_cnt]=head[u]; head[u]=edge_cnt++; } void dfs(int u,int parent,ll d) { dist[u]=d;//记录起点到u的距离 if(d>max_dist)//更新最远距离 { max_dist=d; farthest_node=u;//记录最远节点 } for(int i=head[u];i!=-1;i=next_edge[i]) { int v=to[i]; int w=weight[i]; if(v==parent)continue;//不往回走 dfs(v,u,d+w); } } int main(int argc, char *argv[]) { scanf("%d",&n); memset(head,-1,sizeof(head)); edge_cnt=0; for(int i=0;i<n-1;i++) { int p,q,d; scanf("%d %d %d",&p,&q,&d); add_edge(p,q,d);//添加正向边 add_edge(q,p,d);//添加反向边(无边图) } //第一次DFS:从1出发找最远点 //找直径端点 max_dist=-1; dfs(1,-1,0); int u=farthest_node; //第二次DFS:从u出发找最远点v //找直径长度 max_dist=-1; dfs(u,-1,0); ll diameter=max_dist; ll cost=diameter*(diameter+21)/2; printf("%lld",cost); return 0; }
http://www.cnnetsun.cn/news/1592514.html

相关文章:

  • PyTorch数据预处理全流程:从计算mean/std到实现归一化与反归一化(附完整代码)
  • 视觉语言导航从入门到精通(二):核心模型架构与演进之路
  • Git-FTP 终极指南:如何用Git智能同步FTP部署的完整教程
  • 从零实现一个五子棋AI对手:详解Max-Min算法与Alpha-Beta剪枝在Flutter中的应用
  • 终极Leaf分布式优化指南:如何在多设备上高效训练神经网络
  • PHPBrew补丁机制终极指南:轻松解决特定环境编译问题
  • 避坑指南:ESP8266 wroom_02烧录AT固件时为什么总是卡在等待同步?
  • 【开题答辩全过程】以 基于微信小程序的蓝鲸旧物回收系统的设计与实现为例,包含答辩的问题和答案
  • Wan2.2-I2V-A14B混合云架构:私有核心+公有云弹性扩缩容视频生成方案
  • 别再盲目攻击了!用FIA的‘聚合梯度’思想,让你的对抗样本迁移成功率提升12%
  • DApp革命:当代码成为规则,你的数字人生谁主沉浮?
  • Benchmark.js性能测试数据持久化:完整指南教你保存和比较不同版本性能数据 [特殊字符]
  • Qwen1.5-0.5B-Chat实战部署:Docker容器化改造方案
  • Seed-Coder-8B-Base作品展示:AI生成的代码片段,质量堪比资深程序员
  • Fay框架API版本迁移工具:平滑升级方案
  • 【数据库 面试突击 · 03】大厂高频面试题:从存储过程到索引底层全解析
  • 通义千问3-4B实战:用Ollama三行命令搭建本地AI聊天机器人
  • Bloatynosy vs Winpilot终极对比:桌面应用与Web应用哪个更适合你的Windows优化需求?
  • 回归树 vs 随机森林:如何用Scikit-learn解决实际回归问题(参数调优指南)
  • Rubinius CodeDB揭秘:编译代码存储与管理的终极方案
  • dexcount-gradle-plugin最佳实践:提升Android应用性能的10个技巧
  • 3D-GS进阶实战:手把手教你用Scaffold-GS实现View-Adaptive Rendering(附代码解读)
  • MedGemma-X在基层医院落地案例:低成本部署多模态AI辅助诊断系统
  • 超级电容matlab simulink储能模型仿真,能量管理 蓄电池充放电模型,电池-超级电容混合储能系统能量管理
  • 从单体到SaaS的生死一跃:Java多租户数据隔离配置的6阶段演进路线图(含迁移checklist与回滚SLA)
  • Phi-4-mini-reasoning推理服务成本优化:Spot实例+自动伸缩+冷热启调度
  • 为什么PyTorch团队内部禁用直接Mojo绑定?——揭秘混合编程中隐式内存泄漏的2个反直觉触发场景(附Valgrind检测清单)
  • Vue+Cesium:实战多源地图服务集成与动态切换
  • 【Python】利用Python实现微信公众号文章定时自动发布
  • Pixel Language Portal一文详解:Hunyuan-MT-7B的跨维度语义对齐机制与位置编码改进