news 2026/5/1 8:01:07

洛谷 P2495:[模板] 虚树 / [SDOI2011] 消耗战 ← 虚树 + 树形DP + 倍增

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
洛谷 P2495:[模板] 虚树 / [SDOI2011] 消耗战 ← 虚树 + 树形DP + 倍增

【题目来源】
https://www.luogu.com.cn/problem/P2495

https://www.acwing.com/problem/content/2516/

【题目描述】
在一场战争中,战场由 n 个岛屿和 n-1 个桥梁组成,保证每两个岛屿间有且仅有一条路径可达。现在,我军已经侦查到敌军的总部在编号为 1 的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望。已知在其他 k 个岛屿上有丰富能源,为了防止敌军获取能源,我军的任务是炸毁一些桥梁,使得敌军不能到达任何能源丰富的岛屿。由于不同桥梁的材质和结构不同,所以炸毁不同的桥梁有不同的代价,我军希望在满足目标的同时使得总代价最小。
侦查部门还发现,敌军有一台神秘机器。即使我军切断所有能源之后,他们也可以用那台机器。机器产生的效果不仅仅会修复所有我军炸毁的桥梁,而且会重新随机资源分布(但可以保证的是,资源不会分布到 1 号岛屿上)。不过侦查部门还发现了这台机器只能够使用 m 次,所以我们只需要把每次任务完成即可。

【输入格式】
第一行一个整数 n,表示岛屿数量。
接下来 n-1 行,每行三个整数 u,v,w,表示 u 号岛屿和 v 号岛屿由一条代价为 w 的桥梁直接相连。
第 n+1 行,一个整数 m,代表敌方机器能使用的次数。
接下来 m 行,第 i 行一个整数 k,代表第 i 次后,有 k 个岛屿资源丰富。接下来 ki 个整数 h1,h2,….,hk,表示资源丰富岛屿的编号。

【输出格式】
输出共 m 行,表示每次任务的最小代价。​​​​​​​

【输入样例】
10
1 5 13
1 9 6
2 1 19
2 4 8
2 3 91
5 6 8
7 5 4
7 8 31
10 7 9
3
2 10 6
4 5 7 8 3
3 9 4 6​​​​​​​

【输出样例】
12
32
22​​​​​​​

【数据范围】
对于 10% 的数据,n≤10,m≤5。
对于 20% 的数据,n≤100,m≤100,1≤ki≤10。
对于 40% 的数据,n≤1000,1≤ki≤15。
对于100%的数据,2≤n≤2.5×10^5,1≤m≤5×10^5,Σki≤5×10^5,1≤ki<n,hi≠1,1≤u, v≤n,1≤w≤10^5。

【算法分析】
● 虚树是一种在树形结构问题中用于压缩规模、降低时间复杂度的数据结构,核心思想是只保留问题相关的关键节点,以及这些节点之间的路径关系,从而忽略大量无关节点,让原本无法在大数据范围下运行的算法变得可行。
(1)虚树的核心作用
虚树是
临时数据结构,每组询问都需要根据查询节点重新构建,用完即弃
对一棵 n 量级很大的树(如 1e5/1e6),每次查询只涉及 k 个关键点(k≪n),虚树可以只保留这些关键点间两两的 LCA,构建一棵节点数为 O(k) 的精简树,完美保留原树的“祖先 - 后代”关系、路径拓扑。
(2)虚树必存节点
构建虚树时,必须加入的节点只有两类(缺一不可):
一是本次查询的所有关键点 (去重),二是这些关键点两两之间的最近公共祖先 (LCA)。
(3)虚树的核心性质
虚树的节点数 ≤2k,边数 ≤2k,规模极小;

虚树的边对应原树的一条完整路径,而非原树的单条边;
虚树的根节点和原树根节点一致
虚树是临时结构,每组查询都要重新构建,用完清空即可。

● 快读:
https://blog.csdn.net/hnjzsyjyj/article/details/120131534

int read() { //fast read int x=0,f=1; char c=getchar(); while(c<'0' || c>'9') { //!isdigit(c) if(c=='-') f=-1; c=getchar(); } while(c>='0' && c<='9') { //isdigit(c) x=x*10+c-'0'; c=getchar(); } return x*f; }

● 链式前向星:https://blog.csdn.net/hnjzsyjyj/article/details/139369904

void add(int a,int b,int w) { val[idx]=w,e[idx]=b,ne[idx]=h[a],h[a]=idx++; }

大佬 yxc 指出“链式前向星”就是“多单链表”,每条单链表基于“头插法”并用 e[]、ne[]、h[] 、val[] 等数组进行模拟创建。其中:
e[idx]:存储序号为 idx 的边的终点值
ne[idx]:存储序号为 idx 的边指向的边的序号(模拟链表指针)‌
h[a]:存储头结点 a 指向的边的序号
val[idx]:存储序号为 idx 的边的权值(可选)

【算法代码】

#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N=1e6+5; const int LOG=20; LL val[N],e[N],ne[N],h[N],idx; int stk[N],top; int timestamp; int dfn[N],f[N][LOG+5],a[N],dep[N]; LL ans[N],dp[N]; bool flag[N]; inline int read() { //fast read int x=0,f=1; char c=getchar(); while(c<'0' || c>'9') { //!isdigit(c) if(c=='-') f=-1; c=getchar(); } while(c>='0' && c<='9') { //isdigit(c) x=x*10+c-'0'; c=getchar(); } return x*f; } inline void add(int a,int b,int w) { val[idx]=w,e[idx]=b,ne[idx]=h[a],h[a]=idx++; } inline bool cmp(int x,int y) { return dfn[x]<dfn[y]; } inline void dfs1(int u) { dfn[u]=++timestamp; dep[u]=dep[f[u][0]]+1; for(int i=0; i<=LOG; i++) { if(f[u][i]) f[u][i+1]=f[f[u][i]][i]; else f[u][i+1]=0; } for(int i=h[u]; i!=-1; i=ne[i]) { int j=e[i]; if(!dfn[j]) { f[j][0]=u; dp[j]=min(dp[u],val[i]); dfs1(j); } } h[u]=-1; } inline void dfs2(int u) { LL sum=0; ans[u]=dp[u]; for(int i=h[u]; i!=-1; i=ne[i]) { int j=e[i]; dfs2(j); sum+=ans[j]; } if(sum && !flag[u]) ans[u]=min(ans[u],sum); h[u]=-1; } inline int LCA(int x,int y) { if(dep[x]<dep[y]) swap(x,y); for(int i=LOG; i>=0; i--) { if(dep[f[x][i]]>=dep[y]) x=f[x][i]; } if(x==y) return x; for(int i=LOG; i>=0; i--) { if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; } return f[x][0]; } inline void solve() { top=idx=0; int m=read(); for(int i=1; i<=m; i++) { a[i]=read(); flag[a[i]]=1; } sort(a+1,a+m+1,cmp); for(int i=1; i<=m; i++) { if(!top) { stk[++top]=a[i]; continue; } int lca=LCA(a[i],stk[top]); while(dfn[lca]<dfn[stk[top]]) { if(dfn[lca]>=dfn[stk[top-1]]) { add(lca,stk[top],0); if(stk[--top]!=lca) stk[++top]=lca; break; } add(stk[top-1],stk[top],0); top--; } stk[++top]=a[i]; } while(top>1) { add(stk[top-1],stk[top],0); top--; } dfs2(stk[1]); printf("%lld\n",ans[stk[1]]); for(int i=1; i<=m; i++) flag[a[i]]=0; } int main() { memset(h, -1, sizeof(h)); int n=read(); for(int i=1; i<n; i++) { int x=read(),y=read(),z=read(); add(x,y,z); add(y,x,z); } dp[1]=LLONG_MAX; dfs1(1); int T=read(); while(T--) { solve(); } return 0; } /* in: 10 1 5 13 1 9 6 2 1 19 2 4 8 2 3 91 5 6 8 7 5 4 7 8 31 10 7 9 3 2 10 6 4 5 7 8 3 3 9 4 6 out: 12 32 22 */





【参考文献】
https://www.cnblogs.com/zhenghaotian/p/8243410.html
https://blog.csdn.net/weixin_30539625/article/details/99542716
https://www.luogu.com.cn/problem/solution/P2495
https://www.luogu.com.cn/problem/P4103
https://www.luogu.com.cn/problem/P5680
https://www.cnblogs.com/bztMinamoto/p/10554721.html







版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/25 13:23:52

中兴光猫配置解密工具:让网络配置从此不再神秘

中兴光猫配置解密工具&#xff1a;让网络配置从此不再神秘 【免费下载链接】ZET-Optical-Network-Terminal-Decoder 项目地址: https://gitcode.com/gh_mirrors/ze/ZET-Optical-Network-Terminal-Decoder 你是否曾经因为无法查看光猫配置而苦恼&#xff1f;想要优化家庭…

作者头像 李华
网站建设 2026/4/30 12:39:19

微信防撤回补丁终极指南:简单三步实现消息永久保留

微信防撤回补丁终极指南&#xff1a;简单三步实现消息永久保留 【免费下载链接】RevokeMsgPatcher :trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁&#xff08;我已经看到了&#xff0c;撤回也没用了&#xff09; 项目地址: https://gitcode.com/G…

作者头像 李华
网站建设 2026/4/23 10:20:24

自然语言分割万物!基于sam3大模型镜像快速实现图像精准掩码提取

自然语言分割万物&#xff01;基于sam3大模型镜像快速实现图像精准掩码提取 1. 引言 在计算机视觉领域&#xff0c;图像分割是一项基础而关键的任务&#xff0c;其目标是识别并精确定位图像中每个对象的像素级轮廓。传统方法通常依赖大量标注数据或手动交互&#xff08;如点击…

作者头像 李华
网站建设 2026/4/18 22:09:51

TensorFlow-v2.9模型训练:云端GPU比本地快5倍实测

TensorFlow-v2.9模型训练&#xff1a;云端GPU比本地快5倍实测 你是不是也遇到过这样的情况&#xff1f;团队正在参加一场AI竞赛&#xff0c;模型结构已经调得差不多了&#xff0c;数据也准备好了&#xff0c;结果一跑训练——等了整整一晚上&#xff0c;epoch才跑了三分之一。…

作者头像 李华
网站建设 2026/4/21 22:57:33

免费字体设计新玩法:用FontForge轻松开启你的创意设计之旅

免费字体设计新玩法&#xff1a;用FontForge轻松开启你的创意设计之旅 【免费下载链接】fontforge Free (libre) font editor for Windows, Mac OS X and GNULinux 项目地址: https://gitcode.com/gh_mirrors/fo/fontforge 想要设计属于自己的独特字体&#xff0c;却担心…

作者头像 李华
网站建设 2026/4/18 6:58:25

亲测YOLO26官方镜像,目标检测实战效果惊艳

亲测YOLO26官方镜像&#xff0c;目标检测实战效果惊艳 1. 引言&#xff1a;为何选择YOLO26官方镜像&#xff1f; 在深度学习目标检测领域&#xff0c;YOLO系列凭借其“单次前向传播完成检测”的高效架构&#xff0c;持续引领实时检测技术的发展。随着Ultralytics团队推出新一…

作者头像 李华