题目:给出n个点的树  q次询问  问切断 k个点(不和1号点联通)的最小代价是多少

思路:树形dp  sum[i]表示切断i的子树中需要切断的点的最小代价是多少 mi[i]表示1--i中的最小边权

sum[i]=min(mi[i],sigma(min(mi[v],sum[v]) (v∈i.son))

从根向上dp  这里巧妙运用了欧拉序(每个点入和出的按时间顺序排列的序列)

题目链接:https://www.luogu.org/problemnew/show/P2495

参考:https://www.luogu.org/problemnew/solution/P2495

 #include<bits/stdc++.h>
using namespace std;
const int maxn = ;
typedef long long ll;
const int N=maxn;
struct data{
int v;int nxt;ll val;
}edge[*maxn];
int dfu;
int dfin[N];//欧拉序入的时间戳
int dfou[N];//欧拉序列出的时间戳
int fa[][N];//倍增用
ll mi[N];//i到1号点路径中最小的边权
int dep[N]; //深度
int lca(int u,int v){//倍增lca
if(dep[u]<dep[v])swap(u,v);
int del=dep[u]-dep[v];
for(int i=;del;del>>=,i++){
if(del&){
u=fa[i][u];
}
}//到同一深度
if(u==v)return u;
for(int i=;i>=;i--){
if(fa[i][u]!=fa[i][v]){u=fa[i][u],v=fa[i][v];}
} //从到lca的距离的二进制理解 即可立即为什么fa[0][v]就是是lca
return fa[][v];
}
int alist[maxn],cnt;int n; void dfs(int x){
dfin[x]=++dfu;//首位是入 出 时间戳
for(int i=;fa[i-][x];i++){//更新父节点信息
fa[i][x]=fa[i-][fa[i-][x]];
}
int nxt=alist[x];
while(nxt){//更新最小边权
int v=edge[nxt].v,val=edge[nxt].val;
if(dfin[v]==){
dep[v]=dep[x]+;
mi[v]=min(mi[x],1ll*val);
fa[][v]=x;
dfs(v);
}
nxt=edge[nxt].nxt;
}
dfou[x]=++dfu;
return ;
}
inline void add(int u,int v,ll val)
{ edge[++cnt].v=v;
edge[cnt].nxt=alist[u];
alist[u]=cnt;
edge[cnt].val=val;
}
bool cmp(int x,int y){//分为正负即可方便得判断是入 还是出
int k1=(x>)?dfin[x]:dfou[-x];
int k2=(y>)?dfin[y]:dfou[-y];
return k1<k2;
}
int tr[*N];
stack<int>s;
int m;
bool book[N];
ll sum[N]; int main(){
scanf("%d",&n);
for(int i=;i<=n-;i++){
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);add(y,x,z);
}
mi[]=0x3f3f3f3f;
dfs();//建立欧拉序
scanf("%d",&m);
for(int i=;i<=m;i++){
int tmp;
scanf("%d",&tmp);
for(int j=;j<=tmp;j++){//把要求的点标记
scanf("%d",&tr[j]);
book[tr[j]]=;
sum[tr[j]]=mi[tr[j]];//初始化删除重要点的sum[i](sum指的是切断[i]的子树中所有重要点的最小代价 初始化为切掉该点即 从1--i的最小边权 意思是直接把这个子树切掉了)
}
sort(tr+,tr+tmp+,cmp);//对欧拉序列排序建立虚树
for(int j=;j<tmp;j++){
int lc=lca(tr[j],tr[j+]);
if(!book[lc]){//树的建立
tr[++tmp]=lc;
book[lc]=;
}
}
int nc=tmp;
for(int j=;j<=nc;j++){//把每个点的负时间戳也加入 用负数表示这个的点现在是出去的点
tr[++tmp]=-tr[j];
}
if(!book[]){//强行把1号点加进来当根
tr[++tmp]=;tr[++tmp]=-;
}
sort(tr+,tr+tmp+,cmp);//重构欧拉序
for(int j=;j<=tmp;j++){//模拟dfs 因为1--tmp是欧拉序列 所以可以直接用
if(tr[j]>)s.push(tr[j]);//进栈
else {
int now=s.top();s.pop();
if(now!=){
//状态转移方程sum[i]=sigma(min(mi[v],sum[v]) (v∈i.son)
int fa=s.top();
sum[fa]+=min(sum[now],mi[now]);
}
else printf("%lld\n",sum[]);
sum[now]=;
book[now]=false;
}
}
} return ;
}

P2495 [SDOI2011]消耗战 lca倍增+虚树+树形dp的更多相关文章

  1. BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP+树剖lca

    BZOJ_2286_[Sdoi2011]消耗战_虚树+树形DP Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的 ...

  2. 【BZOJ-2286】消耗战 虚树 + 树形DP

    2286: [Sdoi2011消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2120  Solved: 752[Submit][Status] ...

  3. bzoj 2286(虚树+树形dp) 虚树模板

    树链求并又不会写,学了一发虚树,再也不虚啦~ 2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5002  Sol ...

  4. 【BZOJ-3572】世界树 虚树 + 树形DP

    3572: [Hnoi2014]世界树 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1084  Solved: 611[Submit][Status ...

  5. BZOJ5341[Ctsc2018]暴力写挂——边分治+虚树+树形DP

    题目链接: CSTC2018暴力写挂 题目大意:给出n个点结构不同的两棵树,边有边权(有负权边及0边),要求找到一个点对(a,b)满足dep(a)+dep(b)-dep(lca)-dep'(lca)最 ...

  6. [WC2018]通道——边分治+虚树+树形DP

    题目链接: [WC2018]通道 题目大意:给出三棵n个节点结构不同的树,边有边权,要求找出一个点对(a,b)使三棵树上这两点的路径权值和最大,一条路径权值为路径上所有边的边权和. 我们按照部分分逐个 ...

  7. 2018.09.25 bzoj3572: [Hnoi2014]世界树(虚树+树形dp)

    传送门 虚树入门题? 好难啊. 在学习别人的写法之后终于过了. 这道题dp方程很好想. 主要是不好写. 简要说说思路吧. 显然最优值只能够从子树和父亲转移过来. 于是我们先dfs一遍用儿子更新父亲,然 ...

  8. BZOJ2286 [Sdoi2011]消耗战 【虚树 + 树形Dp】

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 4261  Solved: 1552 [Submit][Sta ...

  9. BZOJ.2286.[SDOI2011]消耗战(虚树 树形DP)

    题目链接 BZOJ 洛谷P2495 树形DP,对于每棵子树要么逐个删除其中要删除的边,要么直接断连向父节点的边. 如果当前点需要删除,那么直接断不需要再管子树. 复杂度O(m*n). 对于两个要删除的 ...

随机推荐

  1. OPC协议解析-OPC客户端与服务器通讯解析

    1      OPC服务器 OPC服务器, 是指按照OPC基金组织规定的OPC规范群开发的软件驱动.OPC服务器作为中间媒介负责从数据源读取数据再跟另外一端的客户端通信.在 OPC客户端/服务器 的结 ...

  2. Android 中使用 dlib+opencv 实现动态人脸检测

    1 概述 完成 Android 相机预览功能以后,在此基础上我使用 dlib 与 opencv 库做了一个关于人脸检测的 demo.该 demo 在相机预览过程中对人脸进行实时检测,并将检测到的人脸用 ...

  3. 【NodeJS】Node.JS 开发环境安装

    1.前言 简单的说 Node.js 就是运行在服务端的 JavaScript. Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台. Node.js是一个事件驱动I/O ...

  4. 前后端分离djangorestframework—— 在线视频平台接入第三方加密防盗录视频

    加密视频 在以后的开发项目中,很可能有做在线视频的,而在线视频就有个问题,因为在线播放,就很有可能视频数据被抓包,如果这个在线视频平台有付费视频的话,这样就会有人做点倒卖视频的生意了,针对这个问题,目 ...

  5. Kafka 安装配置 windows 下

    Kafka 安装配置 windows 下 标签(空格分隔): Kafka Kafka 内核部分需要安装jdk, zookeeper. 安装JDK 安装JDK就不需要讲解了,安装完配置下JAVA_HOM ...

  6. Python(五)模块

    本章内容: 模块介绍 time & datetime random os sys json & picle hashlib XML requests ConfigParser logg ...

  7. Boosting Static Representation Robustness for Binary Clone Search against Code Obfuscation and Compiler Optimization(一)

    接着上一篇,现在明确问题:在汇编克隆搜索文献中,有四种类型的克隆[15][16][17]:Type1.literally identical(字面相同):Type2.syntactically equ ...

  8. 【Python 补充01】Python运算符

    Python运算符 举个简单的例子 4 +5 = 9 . 例子中,4 和 5 被称为操作数,"+" 称为运算符. 1.算术运算符 + - * / # 加减乘除 % # 取模(返回除 ...

  9. nuxt cdn等

    https://blog.csdn.net/xuelang532777032/article/details/78398960

  10. web框架开发-Django简介

    MVC与MTV模型 MVC Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的.松耦合的方式连接在一起,模型负责业务 ...