虚树的核心就是把关键点和关键点的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. asp.net网站Application_Start疑是不执行的现象

    今天遇见了一个很诡异的事情,发布了新代码后,发现在Application_Start中读取的一些配置参数变为空了,最开始我以为是什么特殊的原因程序没有执行Application_Start,导致它们的 ...

  2. leetcood学习笔记-20

    python字符串与列表的相互转换   学习内容: 1.字符串转列表 2.列表转字符串 1. 字符串转列表 str1 = "hi hello world" print(str1.s ...

  3. Shiro学习(8)拦截器机制

    8.1 拦截器介绍 Shiro使用了与Servlet一样的Filter接口进行扩展:所以如果对Filter不熟悉可以参考<Servlet3.1规范>http://www.iteye.com ...

  4. Ubuntu下设置静态网址

    百度上找的图形界面下设置方式: 因为我这里的ubuntu版本是14.10版本 所以我先点击[系统设置],它位置在桌面左侧的菜单栏后面位置. 在系统设置页面,找到[硬件]选项里面的[网络]一项 然后再使 ...

  5. appium无法定位连接的真机元素

    报错信息: com.android.ddmlib.SyncException:Remote object dosen't exist! 解决办法: 错误原因是因为没有dump下来界面的信息保存到uid ...

  6. 剑指offer第二版面试题11:旋转数组的最小数字(JAVA版)

    题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数 ...

  7. python:异常处理及程序调试

    1.异常概述 在程序运行过程中,经常会遇到各种各样的错误.这些错误统称为“异常”,在这些一场中有的是由于开发者将关键词写错导致,这类错误产生的是SyntaxError.invalid syntax(无 ...

  8. 从零起步 系统入门Python爬虫工程师✍✍✍

    从零起步 系统入门Python爬虫工程师 爬虫(又被称为网页蜘蛛,网络机器人)就是模拟客户端发送网络请求,接收请求响应,一种按照一定的规则,自动地抓取互联网信息的程序. 原则上,只要是浏览器(客户端) ...

  9. 2019ICPC南京网络赛B super_log

    题意:求a的a的a次方..一直求b次,也就是在纸上写个a,然后一直a次方a次方,对m取模,记为F(a,b,m)=pow(a,F(a,b-1,phi(m)) 解题思路:联系欧拉降幂,这个迭代的过程,我们 ...

  10. ABP 3.7版本迁移数据库报错未能加载文件或程序集“Castle.Core, Version=4.0.0.0”

    ABP 3.7 3.8版本升级后迁移数据库,报错未能加载文件或程序集“Castle.Core, Version=4.0.0.0”,System.ComponentModel.Annotations也可 ...