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

树上的巧克力-树形DP

树上的巧克力-树形DP

原题

题意

在树上选取两条不重叠的链,使得链上的权值和最大。

思路

很容易想到和树的直径有关,但是我们有两条链,这怎么办?

我们先观察它和直径的关系,发现画出来的图无非是一条直径和一条去掉直径后的直径(和第一条直径连起来也是剩下的直径)。

pZ9bFQU.md.png

所以,我们先求出直径,然后在每个直径上的点求出去掉直径后的直径。(去掉直径就是不能走这条直径),简单算一下时间复杂度,发现在 \(O(n^2)\) 的外表下藏着 \(O(n)\) 的心,可行。

然后就可以快乐度过水样例,发现 \(wa\) 在了第 \(3\) 个点。

仔细考虑一下我们的思路和代码实现,再加上 \(cf\) 大善人送的第 \(3\) 个样例,发现我们的少了两条链都不是直径的情况,这是什么玩意,不是偏离了我们的思路吗?但细细思考会发现,依旧有直径的身影。

pZ9bQSK.md.png

至于求出这样新的两边,我们可以记录直径上每个节点先连且不走直径的最大链。最后最一遍前缀和即可。

实在想不到的话可以用 \(dp\) 把每种状态记录,但是我浪费的时间已经很多了,就不详细展开。

code

#include <bits/stdc++.h>
#define int long long
using namespace std;
constexpr int maxn = 1e5+10;vector<int> gra[maxn];
int n,wi[maxn],di[maxn],c;
int pre[maxn],zj[maxn];// 记录直径节点
bool vis[maxn];int line[maxn];// 节点出去的最大链
int pre_sum[maxn],ma_pre[maxn];
int suf_sum[maxn],ma_suf[maxn];void dfs(int u,int p,int op=1)// 能记录前驱的dfs
{if(op==2){pre[u]=p;}for(int v : gra[u]){if(v==p || vis[v]) continue;di[v]=di[u]+wi[v];if(di[v]>di[c]){c=v;}dfs(v,u,op);}
}signed main()
{#ifndef ONLINE_JUDGEfreopen("cjdl.in","r",stdin);freopen("cjdl.out","w",stdout);#endif // ONLINE_JUDGEscanf("%lld",&n);for(int i=1;i<=n;++i){scanf("%lld",wi+i);}for(int i=1,x,y ;i<n;++i){scanf("%lld%lld",&x,&y);gra[x].emplace_back(y);gra[y].emplace_back(x);}int ans1=0,ans2=0;di[1]=wi[1];// 求一遍直径,并记录节点dfs(1,0);di[c]=wi[c];dfs(c,0,2);ans1+=di[c];// ans1加上直径zj[++zj[0]]=c;vis[c]=1;while(pre[c]){c=pre[c];zj[++zj[0]]=c;vis[c]=1;// 标记}int ma=0;for(int i=1;i<=zj[0];++i){c=zj[i];// 其实没用di[c]=0;// 好像也没用dfs(c,0);if(c==zj[i]) continue;// 如果不能出去line[zj[i]]=di[c];// line就是第一遍dfsdi[c]=wi[c];dfs(c,0);ma=max(ma,di[c]);// 记录最长}ans1+=ma;for(int i=1;i<=zj[0];++i){pre_sum[i]=pre_sum[i-1]+wi[zj[i]];// 直径权值ma_pre[i]=max(ma_pre[i-1],pre_sum[i]+line[zj[i]]);// 算上扩展的line的最大权值}for(int i=zj[0];i>=1;--i){suf_sum[i]=suf_sum[i+1]+wi[zj[i]];ma_suf[i]=max(ma_suf[i+1],suf_sum[i]+line[zj[i]]);}for(int i=0;i<=zj[0];++i){ans2=max(ans2,ma_pre[i]+ma_suf[i+1]);// 取最大}printf("%lld",max(ans1,ans2));return 0;
}
http://www.jsqmd.com/news/37266/

相关文章:

  • 支付宝对接问题归类
  • PRISMA 简介:系统综述和荟萃分析(meta分析)的首选报告项目
  • Topaz Video AI v1.0.5高级版:视频修复黑科技
  • 2025年重庆小程序服务商排名前十强:杰诚智享科技领跑行业
  • 详细介绍:.net AI MCP 入门 适用于模型上下文协议的 C# SDK 简介(MCP)
  • 2025年11月重庆互联网公司推荐排行榜:杰诚智享领跑榜单
  • 一根网线同时接网线和电话线方法
  • NGINX WEBUI Docker 容器化部署指南
  • 2025年重庆抖音推广公司口碑排行榜前十强发布
  • 供应商协同平台有哪些?主要特征与优势是什么?
  • codeql中java相关ql规则一些记录
  • 常见的文件摆渡系统及其安全性与效率分析
  • AI是风口还是泡沫?一个独立开发者的冷思考
  • 银河麒麟桌面操作系统V10SP1(全X86/ARM架构)【ukui-kwin-x11进程占用CPU内存较高】问题解决方法
  • 自动生成提示
  • C. Trinity
  • dongtai-java
  • 雷池 WAF 免费版实测:小白用 Nginx 搭环境,30 分钟护住跨境电商安全
  • Luogu P9128 [USACO23FEB] Fertilizing Pastures G 题解
  • Docker核心概念:镜像、容器、仓库的本质与关联
  • 【知识分享】怎么建立受控的内外网文件传输通道?
  • 什么是文件摆渡系统?数据跨网“桥梁”与安全“卫士”!
  • OpenCL shader
  • 详解 “增益”:从基础概念到电子测量应用
  • 2025年大理石花岗岩生产厂家权威推荐榜单:天然石材/花岗岩/天然大理石源头厂家精选
  • 2025年克拉玛依壁挂炉公司权威推荐榜单:威能壁挂炉/万家乐壁挂炉/天然气壁挂炉服务商精选
  • springboot集成qq邮箱发送邮件
  • R方分数
  • 银河麒麟KylinV10操作系统清理操作系统中的缓存drop_caches
  • CentOS安装JAVA环境