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

树上路径 1(dmy)

树上路径 1(dmy)

题目描述

给你一个 \(n\) 个点的以 \(1\) 为根的树。

给你 \(m\) 条树上的简单路径,每个路径有个权值 \(a_i\)

要求选择一些路径,使得每个点至多在一条路径上,并且路径的权值和最大。

其中 \(1\le n,m \le 2\times 10^3\)

思路

首先你要知道什么是简单路径,简单路径是各顶点不重复的路径,因此是独一无二的。


在一棵树上,对于一个路径 \((u,v,w)\),我们下意识想到分成 \(u\to \text{LCA}\)\(\text{LCA} \to v\)

所以我们就预处理出来每一个路径 \(u,v\)\(\text{LCA}\),先不管有没有用,先预处理出来再说。

因为 \(n\le 2\times 10^3\),我们可以直接暴力预处理。

这样预处理出来还是很有用的,对于一条路径,我们只需要在 \(\text{LCA}\) 处决策即可。


考虑树形 \(\text{dp}\),我们可以这样定义状态:

我们让 \(s\) 作为保底,也就是 \(s[u]\) 代表 \(u\) 完全闲置,不选择任何跨越 \(u\) 的路径,但是其子节点处于自由状态,则:

\[s[u]=\sum\limits_{u\in son_u} dp[v] \]

\(dp[u]\) 代表,以 \(u\) 为根的子树,完全不受祖先干扰时的最大路径,显然这样是能覆盖所有情况的,哪怕不考虑祖先覆盖,到了祖先那一层也会考虑到节点 \(u\),答案是 \(dp[1]\)

自由状态包含强制闲置状态,因此不劣于强制闲置状态,所以 \(dp[u]\ge s[u]\),我们定义损失:

\[l[x]=dp[x]-s[x] \]

表示,如果 \(x\) 被祖先强制覆盖,子树 \(x\) 的收益会减少多少。


对于一条路径 \((u,v,w)\),假设其 \(\text{LCA}\)\(k\),我们只需要在 \(k\) 处选择是否选取。

我们如果选择,那么路径会覆盖 \(u\to k\)\(v\to k\) 的所有节点,也就是让他们强制覆盖。

因此,选这个路径的总收益为:

\[s[k]+w-\sum\limits_{x\in (u\to k)}l[x]-\sum\limits_{x\in (v\to k)}l[x] \]

相对于 \(s[k]\) 的增量:

\[\Delta = w-\sum\limits_{x\in (u\to k)}l[x]-\sum\limits_{x\in (v\to k)}l[x] \]

因为节点 \(k\) 只能选择一条 \(\text{LCA}\)\(k\) 的路径,因此:

\[dp[k]=s[k]+\max(0,\max\limits_{w,lca(u,v)=k}\Delta_{(u,v,w)}) \]

好的,做出来了


时间复杂度

  • 预处理 \(\text{LCA}\)\(\mathcal{O}(nm)\)

  • \(\text{dp}\) 转移的时候,需要遍历每条路径,最坏 \(\mathcal{O}(nm)\)

  • 总时间复杂度 \(\mathcal{O}(nm)\)

完整代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
constexpr int N=2003;int n,m;
int pre[N],dep[N];
int dp[N],s[N];
vector<int> g[N];
struct road {int s,t,len;
};
vector<road> r[N];
void dfs(int u) {for(auto v:g[u]) {dfs(v);s[u]+=dp[v];}dp[u]=s[u];int t=0;for(auto [a,b,c]:r[u]) {int tmp=0;int x=a;while(x!=u) {tmp+=(s[x]-dp[x]);x=pre[x];}x=b;while(x!=u) {tmp+=s[x]-dp[x];x=pre[x];}tmp+=c;t=max(t,tmp);}dp[u]+=t;
}
void init() {}
void solve() {init();cin>>n>>m;for(int i=2; i<=n; i++) {cin>>pre[i];g[pre[i]].push_back(i);dep[i]=dep[pre[i]]+1;}for(int i=1,u,v,w; i<=m; i++) {cin>>u>>v>>w;int x=u,y=v;while(x!=y) {if(dep[x]>dep[y])x=pre[x];else y=pre[y];}r[x].push_back({u,v,w});}dfs(1);cout<<dp[1];
}signed main() {int T=1;while(T--) {solve();}
}

通过倍增可以优化至 \(\mathcal{O}((n+m)\log n)\)

http://www.jsqmd.com/news/1400188/

相关文章:

  • BiliTools快速上手指南:3分钟搞定B站视频一键下载的跨平台免费工具箱
  • 5分钟零代码玩转浏览器AI:手把手体验Teachable Machine图像与声音训练
  • LibreSprite 像素画编辑器实战指南:免费开源,从零到第一帧逐帧动画一次讲透
  • 携程任我行卡闲置了怎么变现?2026年回收渠道价格行情实测分享 - 沃卡回收
  • 终极教程:使用packettracer-fedora脚本一键部署Cisco Packet Tracer最新版
  • 告别复杂状态管理!overlay-kit让React弹窗开发效率提升300%
  • Rust Unsafe 审查:先写不变量,再缩小裸指针范围
  • 合肥GEO优化服务怎么选?2026年本地靠谱服务商与代理加盟推荐指南 - 小随科技
  • OboeTester 音频性能测试全攻略:7 个关卡吃透延迟与卡顿排查
  • 中国行政区划矢量图免费下载:国家省市县四级数据,3步在GIS打开
  • 上海农产品供应服务行业如何选择靠谱的GEO服务商代理加盟?2026年本地推荐指南 - 科技快讯
  • Roblox被锁死在60帧怎么办?RFU帧率解锁工具保姆级免费使用指南
  • 2026甄选:粤泓(深圳)建筑咨询有限公司在钢结构工程资质二级代办领域的专业服务公司解析 - 卓企推荐
  • 合肥汽车用品服务行业GEO服务商怎么选?代理加盟本地靠谱推荐与实战指南 - 科技快讯
  • Maestro 移动端自动化测试设备选型:模拟器与真机差在哪儿,3 个维度帮你快速决定
  • react-native-typescript-transformer错误处理:解决TypeScript编译与运行时常见问题
  • PyWxDump删库事件始末:一封律师函敲响的开源项目合规警钟
  • 【最全下载合集】微软Office全系列官方镜像下载合集(2024-2003)
  • 2026年8月目前刀库生产厂家推荐,龙门加工中心侧铣头/吉辅侧铣头/台湾吉辅铣头/直角加长铣头,刀库生产厂家推荐 - 企业权威推荐大使
  • 2026年澳大利亚海运专线正规服务商实力参考与选型建议 - 滚动商讯
  • 代码折叠终极上手:notepad-- 十分钟摸清万行文件的结构
  • SynologyCloudflareDDNS脚本原理解析:从域名解析到IP自动更新的完整流程
  • 如何用Buzz免费实现离线音频转录?本地Whisper转录工具完整上手指南
  • 上海财税服务企业如何选择靠谱的GEO服务商?2026年本地代理加盟推荐指南 - 科技快讯
  • 上海职业培训服务行业GEO服务商怎么选?2026年本地靠谱代理加盟推荐指南 - 企业新闻快传
  • 3步给你的ESP32 AI设备装上会变脸的表情系统,这份避坑指南请收好
  • 合肥农产品供应企业如何借助GEO抢占AI搜索入口?本地靠谱服务商与代理加盟推荐 - 小随科技
  • 2026年扬州江都区国内GEO服务商代理加盟靠谱推荐:城市合伙人合作模式全指南 - 小随科技
  • 2026年扬州市邗江区GEO服务商代理加盟靠谱推荐:本地创业者选型指南 - 科技快讯
  • 什么是Go语言突变测试?go-mutesting让你的测试质量提升300%的终极指南