BZOJ2286:[SDOI2011]消耗战——题解
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
http://www.lydsy.com/JudgeOnline/problem.php?id=2286
Description
在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达。现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军胜利在望。已知在其他k个岛屿上有丰富能源,为了防止敌军获取能源,我军的任务是炸毁一些桥梁,使得敌军不能到达任何能源丰富的岛屿。由于不同桥梁的材质和结构不同,所以炸毁不同的桥梁有不同的代价,我军希望在满足目标的同时使得总代价最小。侦查部门还发现,敌军有一台神秘机器。即使我军切断所有能源之后,他们也可以用那台机器。机器产生的效果不仅仅会修复所有我军炸毁的桥梁,而且会重新随机资源分布(但可以保证的是,资源不会分布到1号岛屿上)。不过侦查部门还发现了这台机器只能够使用m次,所以我们只需要把每次任务完成即可。Input
第一行一个整数n,代表岛屿数量。
接下来n-1行,每行三个整数u,v,w,代表u号岛屿和v号岛屿由一条代价为c的桥梁直接相连,保证1<=u,v<=n且1<=c<=100000。
第n+1行,一个整数m,代表敌方机器能使用的次数。
接下来m行,每行一个整数ki,代表第i次后,有ki个岛屿资源丰富,接下来k个整数h1,h2,…hk,表示资源丰富岛屿的编号。
Output
输出有m行,分别代表每次任务的最小代价。
Sample Input
10
1 5 13
1 9 6
2 1 19
2 4 8
2 3 91
5 6 8
7 5 4
7 8 31
10 7 9
3
2 10 6
4 5 7 8 3
3 9 4 6Sample Output
12
32
22
UPD 18/5/3:我终于懂虚树啦!以及美化代码。
显然是虚树啊……然而我还是不懂虚树怎么建的……
但是dp十分的简单,就是在虚树上dp[i]表示从i以下的资源节点都到不了i的最小费用。
设u为v的儿子,则:
当u有资源的时候,显然是从v到u的路径中挑一条最小费用的路径割掉即可。
当u没有资源的时候,要么将u往下的资源节点和u断开联系(即将dp[v]+=dp[u]),要么选择从v到u的路径中挑一条最小费用的路径割掉。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cctype>
#include<cstdio>
#include<cmath>
#include<stack>
using namespace std;
typedef long long ll;
const int N=,B=;
const int INF=0x7fffffff;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int w,to,nxt;
}e[*N];
int n,m,cnt,head[N],dep[N];
int anc[N][B+],val[N][B+];
int aux[N],pos[N],stk[N],tot;
int fa_aux[N],tmp[N],num,top;
bool vis[N];
ll dp[N];
inline bool cmp(int a,int b){return pos[a]<pos[b];}
inline void add(int u,int v,int w){
e[++cnt].to=v;e[cnt].w=w;e[cnt].nxt=head[u];head[u]=cnt;
}
void dfs(int u){
pos[u]=++tot;dep[u]=dep[anc[u][]]+;
for(int i=;i<=B;i++){
anc[u][i]=anc[anc[u][i-]][i-];
val[u][i]=min(val[u][i-],val[anc[u][i-]][i-]);
}
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to,w=e[i].w;
if(anc[u][]!=v){
anc[v][]=u;val[v][]=w;
dfs(v);
}
}
}
inline int LCA(int i,int j){
if(dep[i]<dep[j])swap(i,j);
for(int k=B;k>=;--k)
if(dep[anc[i][k]]>=dep[j])i=anc[i][k];
if(i==j)return i;
for(int k=B;k>=;--k)
if(anc[i][k]!=anc[j][k])
i=anc[i][k],j=anc[j][k];
return anc[i][];
}
void build(int t){
sort(aux+,aux+t+,cmp);
num=t;stk[top=]=;
for(int i=;i<=t;i++){
int u=aux[i];
if(!top)fa_aux[u]=,stk[++top]=u;
else{
int lca=LCA(u,stk[top]);
while(dep[stk[top]]>dep[lca]){
if(dep[stk[top-]]<=dep[lca])
fa_aux[stk[top]]=lca;
top--;
}
if(stk[top]!=lca){
fa_aux[lca]=stk[top];
stk[++top]=lca;
aux[++num]=lca;
}
fa_aux[u]=lca;
stk[++top]=u;
}
}
sort(aux+,aux+num+,cmp);
}
inline ll cut(int u,int v){
int res=INF;
for(int i=B;i>=;i--)
if(dep[anc[u][i]]>=dep[v]){
res=min(res,val[u][i]);
u=anc[u][i];
}
return res;
}
void solve(){
for(int i=;i<=num;i++)dp[aux[i]]=;
for(int i=num;i>=;i--){
int u=aux[i],v=fa_aux[u];
if(!vis[u])
dp[v]+=min(dp[u],cut(u,v));
else dp[v]+=cut(u,v);
}
}
int main(){
n=read();
for(int i=;i<n;i++){
int u=read(),v=read(),w=read();
add(u,v,w);add(v,u,w);
}
dfs();
m=read();
while(m--){
int t=read();
for(int i=;i<=t;i++){
int u=read();
aux[i]=tmp[i]=u;vis[u]=;
}
aux[++t]=;
build(t);solve();
printf("%lld\n",dp[]);
for(int i=;i<=t;i++)vis[tmp[i]]=;
}
}
BZOJ2286:[SDOI2011]消耗战——题解的更多相关文章
- [BZOJ2286][SDOI2011]消耗战(虚树DP)
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4998 Solved: 1867[Submit][Statu ...
- BZOJ2286 [Sdoi2011]消耗战 和 BZOJ3611 [Heoi2014]大工程
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6371 Solved: 2496[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]消耗战(虚树模板题附讲解)
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4896 Solved: 1824[Submit][Statu ...
- BZOJ2286:[SDOI2011]消耗战(树形DP,虚树)
Description 在一场战争中,战场由n个岛屿和n-1个桥梁组成,保证每两个岛屿间有且仅有一条路径可达.现在,我军已经侦查到敌军的总部在编号为1的岛屿,而且他们已经没有足够多的能源维系战斗,我军 ...
- 【学习笔记】虚树复习记(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[ ...
随机推荐
- Linux下查看CPU信息[/proc/cpuinfo]
最近在研究linux系统负载的时候,接触到一些关于CPU信息查看的知识,和大家分享一下.通过对/proc/cpuinfo文件中的参数的分析,也学到了不少东西. 在linux操作系统中,CPU的信息在启 ...
- css 网站常用
简单的loading效果 .progressBar { border: solid 1px #303031; font: bold 20px/22px Arial, sans-serif; backg ...
- ping telnet 指令
Ping 一 作用 ping能够辨别网络功能的某些状态,这些状态是日常网络故障诊断的基础.Ping能够识别连接的二进制状态(看是否连通).Ping命令通过过向计算机发送ICMP回应报文并监听回应报文的 ...
- 【SpringCloud】 第十篇: 高可用的服务注册中心
前言: 必需学会SpringBoot基础知识 简介: spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理.服务发现.断路器.路由.微代理.事件总线.全局锁.决策竞选. ...
- 传入中文参数-->服务器_转码的方法
如果要传入 中文参数到 服务器 使用lr_convert_string_encoding() LR_ENC_SYSTEM_LOCALE , 转为 ...
- 「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)
老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有log(n)次) 于是暴力啊暴力,结果我归天了. 好吧,在各种题解的摧残下,我终于出了一篇巨好看(chou lou)代码(很多结构体党 ...
- Flex 布局浅析
除了 CSS 中传统的布局系统之外,CSS3还提供了一个新布局系统.在这个新的框模型中,框的子代采用水平或垂直布局,而且可将未使用的空间分配给特定的子代,或者通过“弹性”分配给应展开的子代,在各子代间 ...
- 承压计算:模拟+double
标题:承压计算 X星球的高科技实验室中整齐地堆放着某批珍贵金属原料. 每块金属原料的外形.尺寸完全一致,但重量不同.金属材料被严格地堆放成金字塔形. 7 ...
- visionpro9.0破解
visionpro9.0软件下载 提供一个visionpro9.0视频教程学习网站:点击下面链接进入. ------------------------Halcon,Visionpro高清视频教程,点 ...
- 关于localStorage的实际应用
在客户端存储数据 HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 之前, ...