虚树的核心就是把关键点和关键点的lca重新生成一棵树,然后在这棵树上进行dp

https://www.cnblogs.com/zwfymqz/p/9175152.html  写的很好的博客

建立虚树的核心代码

void insert(int x){
if(top==){stk[++top]=x;return;}
int lca=LCA(x,stk[top]);
if(lca==stk[top])return;//这里本来要stk[++top]=x的,但是由于本题特殊性,所以删去优化时间
while(top> && dfn[lca]<=dfn[stk[top-]])
add_edge(stk[top-],stk[top]),--top;
if(lca!=stk[top])//如果lca不是关键点,把它做成关键点,即把lca和栈顶元素连边,然后栈顶元素出栈,lca进栈
add_edge(lca,stk[top]),stk[top]=lca;
stk[++top]=x;
}

本题的ac代码

#include<bits/stdc++.h>
using namespace std;
#define maxn 250005
#define ll long long
struct Edge{int to,nxt,w;}e[maxn<<];
int head[maxn],tot;
void add(int u,int v,int w){
e[tot].nxt=head[u];e[tot].to=v;e[tot].w=w;head[u]=tot++;
}
//树链剖分
ll Min[maxn];
int fa[maxn],son[maxn],topf[maxn],size[maxn],d[maxn],dfn[maxn],ind;
void dfs1(int u,int pre){
fa[u]=pre;size[u]=;
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==pre)continue;
d[v]=d[u]+;
Min[v]=min(Min[u],(ll)e[i].w);
dfs1(v,u);
size[u]+=size[v];
if(size[v]>size[son[u]])son[u]=v;
}
}
void dfs2(int u,int tp){
topf[u]=tp;dfn[u]=++ind;
if(!son[u])return;
dfs2(son[u],tp);
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(!topf[v])
dfs2(v,v);
}
}
//求lca
int LCA(int x,int y){
while(topf[x]!=topf[y]){
if(d[topf[x]]<d[topf[y]])
swap(x,y);
x=fa[topf[x]];
}
if(d[x]>d[y])swap(x,y);
return x;
}
//建立虚树 int top,stk[maxn];
vector<int>G[maxn];
void add_edge(int u,int v){G[u].push_back(v);} void insert(int x){
if(top==){stk[++top]=x;return;}
int lca=LCA(x,stk[top]);
if(lca==stk[top])return;
while(top> && dfn[lca]<=dfn[stk[top-]])//把lca以下的关键点都入栈
add_edge(stk[top-],stk[top]),--top;
if(lca!=stk[top])//如果lca不是关键点,把它做成关键点
add_edge(lca,stk[top]),stk[top]=lca;
stk[++top]=x;
}
//在虚树上dp
ll dfs3(int u){
if(G[u].size()==)return Min[u];
ll res=;
for(int i=;i<G[u].size();i++)
res+=dfs3(G[u][i]);
G[u].clear();
return min(res,Min[u]);
} int cmp(int a,int b){return dfn[a]<dfn[b];} int n,m,x,y,z,a[maxn]; int main(){
memset(head,-,sizeof head);
Min[]=1ll<<;
cin>>n;
for(int i=;i<n;i++){
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);add(y,x,z);
}
d[]=;
dfs1(,),dfs2(,); cin>>m;
while(m--){
int k;scanf("%d",&k);
for(int i=;i<=k;i++)scanf("%d",&a[i]);
sort(a+,a++k,cmp);
top=;
stk[top]=;G[].clear(); for(int i=;i<=k;i++)insert(a[i]);
while(top)
add_edge(stk[top-],stk[top]),top--; //进行dp
cout<<dfs3()<<endl;
}
return ;
}

虚树(树形dp套路)模板——bzoj2286的更多相关文章

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

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

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

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

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

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

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

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

  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. 【BZOJ2286】【SDOI2011】消耗战 [虚树][树形DP]

    消耗战 Time Limit: 20 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description 在一场战争中,战场由n个岛屿和n-1 ...

  10. 2018.09.25 bzoj2286: [Sdoi2011]消耗战(虚树+树形dp)

    传送门 又一道虚树入门题. 这个dp更简单啊. 直接记录每个点到1的距离,简单转移就行了. 代码: #include<bits/stdc++.h> #define N 250005 #de ...

随机推荐

  1. python_django_类视图的第一次忐忑碰触!!!

    我们Django学到这里,基础知识阶段是已经完成了!! 在我们前面接触到的视图都是基于函数的视图函数我们可以称它为FBV,而今天我们新接触的就是视图函数的另一类CBV:基于类的视图函数,我们这里拓展这 ...

  2. js实现点击按钮控制展开与收起.

    html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <ti ...

  3. 获取本机IP,本机名称

    InetAddress addr = InetAddress.getLocalHost(); ip=addr.getHostAddress().toString;//获得本机IP address=ad ...

  4. 统计所有小于非负整数 n 的质数的数量,埃拉托斯特尼筛法

    素数的定义:质数又称素数.一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数. 1.暴力算法: 令i=2; 当i<n的时候,我们循环找出2-i的质数,即让i%(2~i-1), ...

  5. Java高并发网络编程(三)NIO

    从Java 1.4开始,Java提供了新的非阻塞IO操作API,用意是替代Java IO和Java Networking相关的API. NIO中有三个核心组件: Buffer缓冲区 Channel通道 ...

  6. CSS3 object-position/object-fit

    object-position和object-fit只针对替换元素有作用,也就是form表单家族控件系列,老牌劲旅img图片,HTML5新贵video视频等元素(一般有src属性的). 一.objec ...

  7. CentOS 7.2 安装MySQL 5.7

    CentOS 7之后的版本yum的默认源中使用MariaDB替代原先MySQL,因此安装方式较为以往有一些改变: 下载mysql的源 wget http://dev.mysql.com/get/mys ...

  8. 【LeetCode 18】四数之和

    题目链接 [题解] 两重循环枚举[i..j]这个区间 同时规定必取nums[i]和nums[j] 那么现在的问题就变成在下标为[i..j]这个区间的数字里面找两个数字使他们的和为target-nums ...

  9. 【Dart学习】-- Dart之异常处理

    概述: Dart2的异常与Java是非常类似的.Dart2的异常是Exception或者Error(包括它们的子类)的类型,甚至可以是非Exception或者Error类,也可以抛出,但是不建议这么使 ...

  10. eclipse中server name选项变灰

    删除workspace中.metadata\.plugins\org.eclipse.core.runtime\.settings目录下 org.eclipse.wst.server.core.pre ...