[bzoj2286] [Sdoi2011消耗战
还是虚树恩。。模板都能打挂QAQ
先在原树上预处理出mndis[i],表示根节点到节点i 路径上边权的最小值(就是断开i与根的联系的最小花费)
建完虚树在虚树上跑树形DP。。f[i]表示断开 i 所在子树内所有有资源的节点 与根节点的联系的最小花费。
若i 节点没资源:f[i]=min( mndis[i] , sigma(f[j]) ),(j是i的儿子,且j所在子树内有有资源的节点)。
若i 节点有资源:f[i]=mndis[i]。。。
链剖大法好。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=;
const int inf=;
struct zs{
int too,pre,dis;
}e[maxn<<];
struct zs1{
int too,pre;
}e1[maxn<<];
int last[maxn],tot,last1[maxn],tot1;
int mndis[maxn],sz[maxn],st[maxn],top;
int dfn[maxn],dep[maxn],bel[maxn],fa[maxn],size[maxn],tim;
int have[maxn],poi[maxn];
int i,j,k,K,n,m,a,b,c;
ll f[maxn]; int ra;char rx;
inline int read(){
rx=getchar(),ra=;
while(rx<''||rx>'')rx=getchar();
while(rx>=''&&rx<='')ra*=,ra+=rx-,rx=getchar();return ra;
} inline void insert(int a,int b,int c){
e[++tot].too=b,e[tot].dis=c,e[tot].pre=last[a],last[a]=tot;
e[++tot].too=a,e[tot].dis=c,e[tot].pre=last[b],last[b]=tot;
}
inline void ins(int a,int b){
// printf(" %d-->%d\n",a,b);
e1[++tot1].too=b,e1[tot1].pre=last1[a],last1[a]=tot1;
} void dfs(int x){
dep[x]=dep[fa[x]]+,size[x]=;
for(int i=last[x];i;i=e[i].pre)
if(e[i].too!=fa[x])
fa[e[i].too]=x,
mndis[e[i].too]=mndis[x]<e[i].dis?mndis[x]:e[i].dis,
dfs(e[i].too),
size[x]+=size[e[i].too];
}
void dfs2(int x,int chain){
int i,mxpos=;bel[x]=chain,dfn[x]=++tim;
for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&size[e[i].too]>=size[mxpos])mxpos=e[i].too;
if(!mxpos)return;
dfs2(mxpos,chain);
for(i=last[x];i;i=e[i].pre)if(e[i].too!=fa[x]&&e[i].too!=mxpos)dfs2(e[i].too,e[i].too);
}
inline int getlca(int a,int b){
if(dep[bel[a]]<dep[bel[a]])swap(a,b);
while(bel[a]!=bel[b]){
a=fa[bel[a]];
if(dep[bel[a]]<dep[bel[b]])swap(a,b);
}
return dep[a]<dep[b]?a:b;
} inline void build(){
register int i,lca;
st[top=]=;
for(i=;i<=K;i++){
lca=getlca(poi[i],st[top]);
while(dfn[st[top]]>dfn[lca])
if(dfn[st[--top]]<=dfn[lca]){
ins(lca,st[top+]);
if(st[top]!=lca)st[++top]=lca;
}else ins(st[top],st[top+]);//,puts("");
st[++top]=poi[i];
}
while(top>)ins(st[top-],st[top]),top--;
}
void query(int x){
int i,to;
f[x]=sz[x]=;
if(have[x]==m){f[x]=mndis[x],sz[x]=;return;}
for(to=e1[i=last1[x]].too;i;to=e1[i=e1[i].pre].too){
query(to);
if(sz[to])f[x]+=f[to],sz[x]+=sz[to];
}
if(x!=&&mndis[x]<f[x])f[x]=mndis[x];
} bool cmp(int a,int b){return dfn[a]<dfn[b];}
int main(){
n=read();
for(i=;i<n;i++)a=read(),b=read(),c=read(),insert(a,b,c);
mndis[]=inf,dfs(),dfs2(,);
// for(i=1;i<=n;i++)printf(" %d\n",mndis[i]); for(m=read();m;m--){
K=read();for(i=;i<=K;i++)have[poi[i]=read()]=m; sort(poi+,poi++K,cmp),
build(),
query(),
printf("%lld\n",f[]); if(m>){for(i=tot1;i;i--)last1[e1[i].too]=;last1[]=tot1=;}
}
return ;
}
[bzoj2286] [Sdoi2011消耗战的更多相关文章
- [BZOJ2286][SDOI2011]消耗战(虚树DP)
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4998 Solved: 1867[Submit][Statu ...
- [BZOJ2286][Sdoi2011]消耗战(虚树上DP)
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6457 Solved: 2533[Submit][Statu ...
- bzoj千题计划254:bzoj2286: [Sdoi2011]消耗战
http://www.lydsy.com/JudgeOnline/problem.php?id=2286 虚树上树形DP #include<cmath> #include<cstdi ...
- BZOJ2286 [Sdoi2011]消耗战 【虚树 + 树形Dp】
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 4261 Solved: 1552 [Submit][Sta ...
- BZOJ2286 [Sdoi2011]消耗战 和 BZOJ3611 [Heoi2014]大工程
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6371 Solved: 2496[Submit][Statu ...
- [Bzoj2286][Sdoi2011]消耗战(虚树模板题附讲解)
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4896 Solved: 1824[Submit][Statu ...
- 【学习笔记】虚树复习记(BZOJ2286 SDOI2011 消耗战)
想写战略游戏却想不起来虚树T^T 所以就有了这篇复习记QwQ ——简介!—— 我们在处理树上问题的时候,dfs是一个常用手段,但是我们发现,如果一棵树上只有一部分关键点,每次dfs需要访问好多不是关键 ...
- [bzoj2286][Sdoi2011]消耗战(虚树上的DP)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2286 分析:对于普通的树形dp:f[x]=min(∑f[son],m[x]),其中f[ ...
- BZOJ2286: [Sdoi2011]消耗战
建出虚树dp. 把询问点按dfs序排序,用一个以dfs序为关键字的单调栈(以深度为关键字也是一样的),每次将一个询问点与栈顶的点的lca入栈,再将这个询问点入栈,在这个过程中建出一棵树就是虚树.具体看 ...
随机推荐
- sqlserver 存储过程 查询
--查询 CREATE PROCEDURE [dbo].[SelelctMessage] @strTable varchar(), --要查询的表 @strColum varchar(), --要查询 ...
- iOS 多线程 简单学习NSThread NSOperation GCD
1:首先简单介绍什么叫线程 可并发执行的,拥有最小系统资源,共享进程资源的基本调度单位. 共用堆,自有栈(官方资料说明iOS主线程栈大小为1M,其它线程为512K). 并发执行进度不可控,对非原子操作 ...
- iOS tableview和 Collection复用机制
TableView的重用机制,为了做到显示和数据分离, tableView的实现并且不是为每个数据项创建一个tableCell.而是只创建屏幕可显示最大个数的cell,然后重复使用这些cell,对ce ...
- S7-200和S7-300profibus-DP通信
一.S7-200CN的cup可以通过EM277接入DP网络 二.CPU315-2DP做主站,S7-200CUP做从站 三. 通信题目 四.硬件组态 1.主站的DP组态,地址为2 2.EM277作为从站 ...
- 解题思路:best time to buy and sell stock i && ii && iii
这三道题都是同一个背景下的变形:给定一个数组,数组里的值表示当日的股票价格,问你如何通过爱情买卖来发家致富? best time to buy and sell stock i: 最多允许买卖一次 b ...
- C#又能出来装个B了。一步一步微信跳一跳自动外挂
PS:语言只是载体.思维逻辑才是王道 前天看见了个python的脚本.于是装python.配置环境变量.装pip.折腾了一上午,最终装逼失败. 于是进入博客园,顶部有篇文章吸引了我 .NET开发一个微 ...
- lesson - 2 yum /单用户/救援模式/Linux 启动
课程大纲:1. yum使用yum 是一个在线安装软件包的工具,它可以帮我们解决软件包的依赖,这个日后会详细介绍.我们介绍了以下几个用法:yum list 这个命令可以列出所有安装过和未安装的软 ...
- crm踩坑记(三)
React 如何同步更新state 由于setState方法是异步的,而通常很多时候在一个生命周期里更新state后需要在另一个生命周期里使用这个state. 下面介绍几个方法 // 1 this.s ...
- Illustration of Git branching and merge
网上看到的描述Git工作流程的图片,有些出处忘了保存,仅供学习. 1. One Git Branching Model 出处: http://nvie.com/posts/a-successful-g ...
- java推送数据到app--极光推送
之前项目有用到需要把数据推送到app端 采用的是极光推送 特此把工具类和pom.xml需要的jar整理如下 pom.xml需要jar如下 <!-- 极光推送 --> <depende ...