【BZOJ】2286: [Sdoi2011]消耗战 虚树+DP
【题意】给定n个点的带边权树,每次询问给定ki个特殊点,求隔离点1和特殊点的最小代价。n<=250000,Σki<=500000。
【算法】虚树+DP
【题解】考虑普通树上的dp,设f[x]表示隔离1和子树x内特殊点的最小代价,val[x]表示x到1路径上的最小代价(预处理)。
点x特殊,f[x]=val[x]
否则,f[x]=min{val[x],Σf[y]},y=son[x]
在询问总数有限制的前提下,可以建虚树进行如上DP。
复杂度O(Σki log n)。
注意:
1.清空时垃圾回收,保证复杂度。
2.询问点数组开两倍,因为要加入两两LCA。
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
int read(){
int s=,t=;char c;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
const int maxn=;
struct edge{int v,w,from;}e[maxn*];
int in[maxn],ou[maxn],deep[maxn],f[maxn][],st[maxn],n,N,tot,first[maxn],a[maxn*];//a[]
bool v[maxn];
ll val[maxn]; namespace cyc{
struct edge{int v,w,from;}e[maxn*];
int first[maxn],dfsnum=,tot;
void insert(int u,int v,int w){tot++;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;}
void dfs(int x,int fa){
in[x]=++dfsnum;
for(int j=;(<<j)<=deep[x];j++)f[x][j]=f[f[x][j-]][j-];
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa){
deep[e[i].v]=deep[x]+;
val[e[i].v]=min(val[x],1ll*e[i].w);
f[e[i].v][]=x;
dfs(e[i].v,x);
}
ou[x]=dfsnum;
}
int lca(int x,int y){
if(deep[x]<deep[y])swap(x,y);
int d=deep[x]-deep[y];
for(int i=;i<=;i++)if((<<i)&d)x=f[x][i];
if(x==y)return x;
for(int i=;i>=;i--)if((<<i)<=deep[x]&&f[x][i]!=f[y][i]){
x=f[x][i];y=f[y][i];
}
return f[x][];
}
void build(){
n=read();
for(int i=;i<n;i++){
int u=read(),v=read(),w=read();
insert(u,v,w);insert(v,u,w);
}
val[]=1ll<<;//
dfs(,-);
}
}
void insert(int u,int v){tot++;e[tot].v=v;e[tot].from=first[u];first[u]=tot;}
bool cmp(int a,int b){return in[a]<in[b];}
ll dp(int x){
if(v[x])return val[x];
ll sum=;
for(int i=first[x];i;i=e[i].from)sum+=dp(e[i].v);
return min(val[x],sum);
}
bool check(int x,int y){return in[y]<=in[x]&&ou[x]<=ou[y];}
void build(){
int last=read();N=last;
for(int i=;i<=N;i++)a[i]=read(),v[a[i]]=;//
sort(a+,a+N+,cmp);
for(int i=;i<last;i++)a[++N]=cyc::lca(a[i],a[i+]);
sort(a+,a+N+,cmp);
N=unique(a+,a+N+)-a-;
for(int i=;i<=N;i++)first[a[i]]=;tot=;//
int top=;
for(int i=;i<=N;i++){
while(top&&!check(a[i],st[top]))top--;
if(top)insert(st[top],a[i]);
st[++top]=a[i];
}
printf("%lld\n",dp(a[]));
for(int i=;i<=N;i++)v[a[i]]=;//
}
int main(){
cyc::build();
int m=read();
while(m--)build();
return ;
}
【BZOJ】2286: [Sdoi2011]消耗战 虚树+DP的更多相关文章
- bzoj 2286 [Sdoi2011]消耗战 虚树+dp
题目大意:多次给出关键点,求切断边使所有关键点与1断开的最小费用 分析:每次造出虚树,dp[i]表示将i和i子树与父亲断开费用 对于父亲x,儿子y ①y为关键点:\(dp[x]\)+=\(dismn( ...
- bzoj 2286: [Sdoi2011]消耗战 虚树+树dp
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MB[Submit][Status][Discuss] Description 在一 ...
- BZOJ 2286: [Sdoi2011]消耗战 虚树 树形dp 动态规划 dfs序
https://www.lydsy.com/JudgeOnline/problem.php?id=2286 wa了两次因为lca犯了zz错误 这道题如果不多次询问的话就是裸dp. 一棵树上多次询问,且 ...
- BZOJ.2286.[SDOI2011]消耗战(虚树 树形DP)
题目链接 BZOJ 洛谷P2495 树形DP,对于每棵子树要么逐个删除其中要删除的边,要么直接断连向父节点的边. 如果当前点需要删除,那么直接断不需要再管子树. 复杂度O(m*n). 对于两个要删除的 ...
- BZOJ 2286 [Sdoi2011]消耗战 ——虚树
虚树第一题. 大概就是建一颗只与询问有关的更小的新树,然后在虚树上DP #include <map> #include <ctime> #include <cmath&g ...
- BZOJ 2286: [Sdoi2011]消耗战 虚树
Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军 ...
- [BZOJ2286][SDOI2011]消耗战(虚树DP)
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4998 Solved: 1867[Submit][Statu ...
- BZOJ 2286: [Sdoi2011]消耗战
2286: [Sdoi2011消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2082 Solved: 736[Submit][Status] ...
- BZOJ 3572 [HNOI2014]世界树 (虚树+DP)
题面:BZOJ传送门 洛谷传送门 题目大意:略 细节贼多的虚树$DP$ 先考虑只有一次询问的情况 一个节点$x$可能被它子树内的一个到x距离最小的特殊点管辖,还可能被管辖fa[x]的特殊点管辖 跑两次 ...
随机推荐
- linux防火墙,高级策略策略实例详解(实例一)
双线服务器的控制问题: 要求:写出这个电信用户访问到双线web服务器时的IP变化过程(只写源IP,目标IP,和做SNAT还是DNAT等) 你觉得有没有问题? 实验环境: 精简一点可以使用下面的四台虚拟 ...
- Python之面向对象编程学习
不知不觉,学到了python的面向对象编程思想.今天我们来讨论下面向对象编程的思想. 顾名思义,面向对象,就是面向于对象,这里所说的对象不是你现实生活中你的女朋友,你的老婆,你的爱人,在编程的世界里面 ...
- 解题:SDOI2018 战略游戏
题面 先圆方树然后建虚树,答案就是虚树大小.虚树没必要建出来,把原来的点的点权设为1,直接dfs序排序后相邻点求距离加上首尾两个点的距离,最后除以二(画一下可以发现是正反算了两遍),注意还要去掉询问点 ...
- 每添加一张图片后,GDI对象 + 3 原因: ImageList_AddIcon(hIcon) 后没调用 DestroyIcon(hIcon)
今天无意间在[任务管理器]中发现,每添加1张图片后,应用程序的 GDI对象 + 3,添加图片后,再把所有图片删除, GDI对象数量没减少! 排查原因,发现: GDI对象 + 3 的代码是: int o ...
- Unity 着色过程
图形API包括:OpenGL.Metal.Vulkan.Director3D. 渲染管线(图形管线)通用结构: 1.数据收集(图形的网格.纹理.材质)--------2.顶点着色器(获取图形的2D坐标 ...
- HDU 1880 魔咒词典 (Hash)
魔咒词典 Time Limit: 8000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- (编辑距离问题 线性DP) nyoj1431-DNA基因鉴定
题目描述: 我们经常会听说DNA亲子鉴定是怎么回事呢?人类的DNA由4个基本字母{A,C,G,T}构成,包含了多达30亿个字符.如果两个人的DNA序列相差0.1%,仍然意味着有300万个位置不同,所以 ...
- ajax请求封装函数
写封装函数的套路 1.先写出这个函数原来的基本用法 2.写一个没有形参空函数,将上一步的代码直接作为函数体, 3.根据使用过程中,抽象出来需要变的东西作为形参 function ajax (metho ...
- SQLMAP UDF提权
SQLMAP UDF提权 1.连接mysql数据打开一个交互shell: sqlmap.py -d mysql://root:root@127.0.0.1:3306/test --sql-s ...
- 推荐几个Mac插件帮你提升工作效率
下面这篇文章是小编看到的很好的文章,分享给大家,小编前几天也整理了很多mac专题文章.更多专题,可关注[磨人的小妖精],查看我的文章,也可上[风云社区 SCOEE],查找和下载相关软件资源. (一)综 ...