BZOJ 2286: [Sdoi2011]消耗战 虚树 树形dp 动态规划 dfs序
https://www.lydsy.com/JudgeOnline/problem.php?id=2286
wa了两次因为lca犯了zz错误

这道题如果不多次询问的话就是裸dp。
一棵树上多次询问,且总共询问的点数较小(能够承受得住加个logn的复杂度(常数就不管了,按理说还要*2吧))可以用虚树来处理。
虚树就是对每次询问将有用的点建一棵树,每次询问查询m个点,则这棵树最多m*2个点(太优秀了)。
这个虚树的建立过程是用栈维护一条链,每加入一个点就把她和前一条链的叶子节点的lca和这个点本身加入虚树中,然后将当前链的叶子节点改为当前加入的点。
dfs序是个好东西,它帮助维护了这条链和后面点的关系(的逻辑性?(看到代码就懂了吧,反正就很有逻辑就对了))。
所以我之前为什么要学树链剖分,树链剖分什么用都没有嘤嘤嘤,最喜欢倍增了。(日常抛弃旧爱)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
#define LL long long
const int maxn=;
const LL minf=(LL)5e17;
int n,m;
struct nod{
int nex,y,v;
};nod e[maxn*];nod e1[maxn*];
int head[maxn]={},tot=;
int head1[maxn]={},tot1=;
int id[maxn]={},cnt=;
int fa[maxn][]={},dep[maxn]={};
LL dis[maxn]={},f[maxn]={};
int a[maxn]={},tly=;
int sta[maxn]={},tai=;
inline int mread(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void init(int x,int y,int v){
e[++tot].y=y;e[tot].v=v;e[tot].nex=head[x];head[x]=tot;
}
inline void init1(int x,int y){
if(x==y)return;
e1[++tot1].y=y;e1[tot1].nex=head1[x];head1[x]=tot1;
}
void dfs(int x,int pa){
fa[x][]=pa;id[x]=++cnt;
for(int i=;fa[fa[x][i-]][i-]!=;++i)fa[x][i]=fa[fa[x][i-]][i-];
for(int i=head[x];i;i=e[i].nex){
int y=e[i].y;
if(y==pa)continue;
dis[y]=dis[x]<e[i].v?dis[x]:e[i].v;
dep[y]=dep[x]+;
dfs(y,x);
}
}
bool mcmp(int x,int y){return id[x]<id[y];}
int getlca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int i=;i>=;--i){
if(!fa[x][i])continue;
if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
if(dep[x]==dep[y])break;
}
if(x==y)return x;
for(int i=;i>=;--i){
if(!fa[x][i])continue;
if(fa[x][i]!=fa[y][i]){x=fa[x][i];y=fa[y][i];}
}
return fa[x][];
}
void dfs1(int x){
f[x]=dis[x];LL v=;
for(int i=head1[x];i;i=e1[i].nex){
dfs1(e1[i].y);
v+=f[e1[i].y];
}
if(v)f[x]=min(f[x],v);
head1[x]=;
}
void cutit(){
int q=mread(); for(int i=;i<=q;++i)a[i]=mread();
sort(a+,a++q,mcmp); tly=;
for(int i=;i<=q;++i){if(getlca(a[i],a[tly])!=a[tly])a[++tly]=a[i];}
//由根节点到叶子节点的每条链上至多只有一个点
tai=;sta[]=;tot1=;int lc;
for(int i=;i<=tly;i++){//sta按照dfs序维护了一条链
lc=getlca(sta[tai],a[i]);
for(;tai>;){//更改链向下延伸的方向,把之前方向的点连上
if(dep[sta[tai-]]<=dep[lc]){
init1(lc,sta[tai]);tai--;
if(sta[tai]!=lc)sta[++tai]=lc;
break;
}init1(sta[tai-],sta[tai]);tai--;
}
if(sta[tai]!=a[i])sta[++tai]=a[i];
}
while(--tai)init1(sta[tai],sta[tai+]);
dfs1();
printf("%lld\n",f[]);
}
int main(){
int x,y,v;
n=mread();
for(int i=;i<n;++i){
x=mread();y=mread();v=mread();
init(x,y,v);init(y,x,v);
}
dis[]=minf; dep[]=; dfs(,);
m=mread(); for(int i=;i<=m;++i) cutit();
return ;
}
BZOJ 2286: [Sdoi2011]消耗战 虚树 树形dp 动态规划 dfs序的更多相关文章
- BZOJ.2286.[SDOI2011]消耗战(虚树 树形DP)
题目链接 BZOJ 洛谷P2495 树形DP,对于每棵子树要么逐个删除其中要删除的边,要么直接断连向父节点的边. 如果当前点需要删除,那么直接断不需要再管子树. 复杂度O(m*n). 对于两个要删除的 ...
- bzoj 2286: [Sdoi2011]消耗战 虚树+树dp
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MB[Submit][Status][Discuss] Description 在一 ...
- bzoj 2286 [Sdoi2011]消耗战 虚树+dp
题目大意:多次给出关键点,求切断边使所有关键点与1断开的最小费用 分析:每次造出虚树,dp[i]表示将i和i子树与父亲断开费用 对于父亲x,儿子y ①y为关键点:\(dp[x]\)+=\(dismn( ...
- BZOJ 2286: [Sdoi2011]消耗战 虚树
Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军 ...
- BZOJ2286: [Sdoi2011]消耗战(虚树/树形DP)
Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 5246 Solved: 1978[Submit][Status][Discuss] Descript ...
- BZOJ 2286 [Sdoi2011]消耗战 ——虚树
虚树第一题. 大概就是建一颗只与询问有关的更小的新树,然后在虚树上DP #include <map> #include <ctime> #include <cmath&g ...
- 【BZOJ-2286】消耗战 虚树 + 树形DP
2286: [Sdoi2011消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2120 Solved: 752[Submit][Status] ...
- BZOJ 2286 消耗战 (虚树+树形DP)
给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...
- 【BZOJ】2286: [Sdoi2011]消耗战 虚树+DP
[题意]给定n个点的带边权树,每次询问给定ki个特殊点,求隔离点1和特殊点的最小代价.n<=250000,Σki<=500000. [算法]虚树+DP [题解]考虑普通树上的dp,设f[x ...
随机推荐
- 《区块链100问》第81集:应用类项目Augur
Augur是基于以太坊区块链打造的去中心化预测平台,于2015年6月正式发布,是以太坊上的第一款应用. Augur采用了一个叫“群体智慧”的概念,它的意思是,一群人的智慧会高于这群人中最聪明的人.所以 ...
- 【转】Spring MVC 标签总结
1.@Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ...
- mycat读写分离与主从切换【转】
什么是mycat,以及mycat的优点和特性本文不做赘述,本文继续本着实战的态度,来分享一些个人对mycat的基础功能实践.本文mycat的读写分离和主从切换的环境为mysql主从环境. 如何安装my ...
- 众签demo
众签demo using System; using System.Collections.Generic; using System.Linq; using System.Text; using S ...
- 最长子串(Leetcode-3 Longest Substring Without Repeating Characters)
Question: Given a string, find the length of the longest substring without repeating characters. Exa ...
- 修改类不用重启Tomcat加载整个项目
可以修改类不用重启Tomcat加载整个项目(手工启动) 配置reloadable=true(自动重载) 使用Debug模式,前提是仅限于局部修改.(修改类不用重启--热加载) Tomcat轻小,而We ...
- Python_oldboy_自动化运维之路(八)
本节内容: 列表生成式,迭代器,生成器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器,生成器 1.列表生成式 #[列表生成] #1.列 ...
- URL的井号
2010年9月,twitter改版. 一个显著变化,就是URL加入了"#!"符号.比如,改版前的用户主页网址为 http://twitter.com/username 改版后,就变 ...
- OpenCV与Python之图像的读入与显示以及利用Numpy的图像转换
1:读入图像,显示图像与保存图像 代码: import cv2 img=cv2.imread('lena.jpg',cv2.IMREAD_COLOR) cv2.namedWindow('lena',c ...
- JavaScript 中的回调函数
原文:http://javascriptissexy.com/ 翻译:http://blog.csdn.net/luoweifu/article/details/41466537 [建议阅读原文,以下 ...