题面:

传送门

思路:

看到所有询问中的点数总和是十万级别的,就想到用虚树~\(≧▽≦)/~啦

首先,树形dp应该是很明显可以看出来的:

设dp[u]表示以u为根的子树(不包括u)中的宝藏岛全部切断的最小需要值

那么显然dp[u]等于所有dp[v]的和(v是u的儿子)与从根(一号结点)到u的路径上的最小边权之间的最小值

然后dp[1]就是答案了

建出虚树然后dp,$O\left(n\right)$解决

Code:

 /#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#define ll long long
using namespace std;
const long long inf=(1ll<<50ll);
inline ll read(){
ll re=,flag=;char ch=getchar();
while(ch>''||ch<''){
if(ch=='-') flag=-;
ch=getchar();
}
while(ch>=''&&ch<='') re=(re<<)+(re<<)+ch-'',ch=getchar();
return re*flag;
}
ll n,m,dep[],fa[],st[][],dfn[],clk,minn[];
struct graph{
ll first[],cnt;
struct edge{
ll to,next,w;
}a[];
inline void add(ll u,ll v,ll w){
if(u==v) return;
a[++cnt]=(edge){v,first[u],w};first[u]=cnt;
}
void init(){
cnt=;
}
}G,g;
void dfs(ll u,ll f){
ll i,v;fa[u]=st[u][]=f;dfn[u]=++clk;dep[u]=dep[f]+;
for(i=G.first[u];~i;i=G.a[i].next){
v=G.a[i].to;
if(v==f) continue;
minn[v]=min(minn[u],G.a[i].w);
dfs(v,u);
}
}
void ST(){
ll i,j;
for(j=;j<=;j++){
for(i=;i<=n;i++) st[i][j]=st[st[i][j-]][j-];
}
}
ll lca(ll l,ll r){
if(dep[l]>dep[r]) swap(l,r);
ll i;
for(i=;i>=;i--) if(dep[st[r][i]]>=dep[l]) r=st[r][i];
if(l==r) return l;
for(i=;i>=;i--)
if(st[l][i]!=st[r][i]){
l=st[l][i];
r=st[r][i];
}
return fa[l];
}
ll q[],tot,s[],top,num,f[];
bool cmp(ll l,ll r){
return dfn[l]<dfn[r];
}
void dp(ll u){
ll i,v,tmp=;
for(i=g.first[u];~i;i=g.a[i].next){
v=g.a[i].to;g.first[u]=g.a[i].next;
dp(v);tmp+=f[v];
}
if(!tmp) f[u]=minn[u];
else f[u]=min(minn[u],tmp);
}
int main(){
ll i,t1,t2,t3,j;
n=read();memset(G.first,-,sizeof(G.first));
for(i=;i<n;i++){
t1=read();t2=read();t3=read();
G.add(t1,t2,t3);G.add(t2,t1,t3);
}
minn[]=inf;
dfs(,);ST();
m=read();memset(g.first,-,sizeof(g.first));
for(i=;i<=m;i++){
tot=read();//memset(q,0,sizeof(q));
for(j=;j<=tot;j++) q[j]=read(),assert(q[j]<=n);
sort(q+,q+tot+,cmp);g.init();
num=;q[++num]=q[];
for(j=;j<=tot;j++) if(lca(q[j],q[num])!=q[num]) q[++num]=q[j];
s[++top]=;ll grand;
for(j=;j<=num;j++){
if(q[j]==) return *(int*);
grand=lca(q[j],s[top]);
while(){
if(dep[s[top-]]<=dep[grand]){
g.add(grand,s[top--],);
if(s[top]!=grand) s[++top]=grand;
break;
}
g.add(s[top-],s[top],);top--;
}
if(s[top]!=q[j]) s[++top]=q[j];
}
while(--top) g.add(s[top],s[top+],);
dp();
printf("%lld\n",f[]);
}
}

[SDOI2011][bzoj2286] 消耗战 [虚树+dp]的更多相关文章

  1. [BZOJ2286][SDOI2011]消耗战(虚树DP)

    2286: [Sdoi2011]消耗战 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4998  Solved: 1867[Submit][Statu ...

  2. bzoj 2286 [Sdoi2011]消耗战 虚树+dp

    题目大意:多次给出关键点,求切断边使所有关键点与1断开的最小费用 分析:每次造出虚树,dp[i]表示将i和i子树与父亲断开费用 对于父亲x,儿子y ①y为关键点:\(dp[x]\)+=\(dismn( ...

  3. 【BZOJ】2286: [Sdoi2011]消耗战 虚树+DP

    [题意]给定n个点的带边权树,每次询问给定ki个特殊点,求隔离点1和特殊点的最小代价.n<=250000,Σki<=500000. [算法]虚树+DP [题解]考虑普通树上的dp,设f[x ...

  4. 【BZOJ2286】【SDOI2011】消耗战 [虚树][树形DP]

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

  5. LG2495 「SDOI2011」消耗战 虚树

    问题描述 LG2495 题解 虚树 \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace std; #define int l ...

  6. 洛谷P2495 [SDOI2011]消耗战(虚树dp)

    P2495 [SDOI2011]消耗战 题目链接 题解: 虚树\(dp\)入门题吧.虚树的核心思想其实就是每次只保留关键点,因为关键点的dfs序的相对大小顺序和原来的树中结点dfs序的相对大小顺序都是 ...

  7. [SDOI2011]消耗战(虚树+树形动规)

    虚树dp 虚树的主要思想: 不遍历没用的的节点以及没用的子树,从而使复杂度降低到\(\sum\limits k\)(k为询问的节点的总数). 所以怎么办: 只把询问节点和其LCA放入询问的数组中. 1 ...

  8. bzoj 3572世界树 虚树+dp

    题目大意: 给一棵树,每次给出一些关键点,对于树上每个点,被离它最近的关键点(距离相同被标号最小的)控制 求每个关键点控制多少个点 分析: 虚树+dp dp过程如下: 第一次dp,递归求出每个点子树中 ...

  9. [BZOJ5287][HNOI2018]毒瘤(虚树DP)

    暴力枚举非树边取值做DP可得75. 注意到每次枚举出一个容斥状态的时候,都要做大量重复操作. 建立虚树,预处理出虚树上两点间的转移系数.也可动态DP解决. 树上倍增.动态DP.虚树DP似乎是这种问题的 ...

随机推荐

  1. CSS布局--垂直水平居中

    ···设置两个盒子 <div class="parent"> <div class="child"> </div></ ...

  2. 实现带查询功能的ComboBox控件

    实现效果: 知识运用: ComboBox控件的AutoCompleteMode属性 public AutoCompleteMode AutoCompleteMode{get;set;} //属性值为枚 ...

  3. DongDong坐飞机

    题目连接:https://ac.nowcoder.com/acm/contest/904/D 第一次研究了一下这种题型,还是比较好理解的,因为有半价次数的限制,所以要把每一中情况都写出来,dp[现在的 ...

  4. AFN post的数据编码格式问题

    想到写任何关于AFN的东西其实我是拒绝的,因为自己这也是第一次用,毕竟AFN现在是最为流行的网络框架了,害怕自己理解的有误,所以不敢造次! 先在这里大致讲解一下过程吧,后期发现了再更正(主要是想让看官 ...

  5. SummerVocation_Leaning--java动态绑定(多态)

    概念: 动态绑定:在执行期间(非编译期间)判断所引用的对象的实际类型,根据实际类型调用其相应的方法.如下例程序中,根据person对象的成员变量pet所引用的不同的实际类型调用相应的方法. 具体实现好 ...

  6. 精致的系统监控工具-netdata

    今天在网上瞎逛,偶然发现一款监控工具:netdata,感到一惊,监控工具竟然可以这么漂亮! 简单了解一下,这款工具还算比较新,监控系统运行状态的功能非常强大,除了监控cpu,网卡,磁盘,内存,进程等等 ...

  7. 安装并配置多实例Mysql数据库

    1.安装Mysql需要的依赖包 yum -y install ncurses-devel libaio-devel cmake 2.创建Mysql用户账号 useradd -s /sbin/nolog ...

  8. 多页应用 Webpack4 配置优化与踩坑记录

    前言 最近新起了一个多页项目,之前都未使用 webpack4 ,于是准备上手实践一下.这篇文章主要就是一些配置介绍,对于正准备使用 webpack4 的同学,可以做一些参考. webpack4 相比之 ...

  9. (转)RubyGems常用命令

    什么是RubyGems? RubyGems是一个方便而强大的Ruby程序包管理器,Ruby的第三方插件是用gem方式来管理,非常容易发布和共享,一个简单的命令就可以安装上第三方的扩展库.特点:能远程安 ...

  10. Kali 中文家目录改英文目录

    中文版Kali装好之后,家目录会中文显示,不便操作 root@kali:~# ls -l drwxr-xr-x root root .0K 7月 : 公共 drwxr-xr-x root root . ...