【bzoj3991】 寻宝游戏
http://www.lydsy.com/JudgeOnline/problem.php?id=3991 (题目链接)
题意
给出一个n个节点的带权树,m次操作每次修改一个关键点,求每次操作后,从其中任意一个关键点出发走遍所有关键点再走回起点所需的最小花费。
solution
假如没有修改操作的话,就像一个简单的在虚树上树形DP,方程如下:$${f[i]=\sum{f[son]}+\sum{e.w*2}}$$
观察一下DP的过程,就是不断地从前面的点走到后面的点,所以我们可以不用这么麻烦,直接按关键点的dfs序排序走一遍就可以了。我们不构造虚树,而是用set维护修改操作,修改的时候只是加入或删除其中的一个点,所以找到这个点的前驱和后继也就是lower_bound-1和upper_bound,计算一下对答案的影响就好了,最后注意要回起点和开LL。
代码
// bzoj3991
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<set>
#define MOD 1000000007
#define inf 2147483647
#define LL long long
#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
using namespace std;
inline LL getint() {
LL x=0,f=1;char ch=getchar();
while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
} const int maxn=100010;
struct edge {int next,to,w;}e[maxn<<2];
int head[maxn],fa[maxn][20],bin[20],deep[maxn],b[maxn],num[maxn],dfn[maxn],a[maxn];
int cnt,n,m;
LL w[maxn];
set<int> s; void insert(int u,int v,int w) {
e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;
e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;e[cnt].w=w;
}
void dfs(int u) {
dfn[u]=++cnt;num[cnt]=u;
for (int i=1;i<20;i++) fa[u][i]=fa[fa[u][i-1]][i-1];
for (int i=head[u];i;i=e[i].next) if (e[i].to!=fa[u][0]) {
w[e[i].to]=w[u]+(LL)e[i].w;
deep[e[i].to]=deep[u]+1;
fa[e[i].to][0]=u;
dfs(e[i].to);
}
}
int lca(int x,int y) {
if (deep[x]<deep[y]) swap(x,y);
int t=deep[x]-deep[y];
for (int i=0;bin[i]<=t;i++) if (bin[i]&t) x=fa[x][i];
for (int i=19;i>=0;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return x==y?x:fa[x][0];
}
LL dis(int x,int y) {
return w[x]+w[y]-2*w[lca(x,y)];
}
int main() {
bin[0]=1;for (int i=1;i<20;i++) bin[i]=bin[i-1]<<1;
scanf("%d%d",&n,&m);
for (int i=1;i<n;i++) {
int u=getint(),v=getint(),w=getint();
insert(u,v,w);
}
cnt=0;
dfs(1);
LL ans=0;
s.insert(inf);s.insert(-inf);
while (m--) {
LL x=getint(),t;
if (b[x]) s.erase(dfn[x]),t=-1;
else s.insert(dfn[x]),t=1;
b[x]^=1;
int l=*--s.lower_bound(dfn[x]),r=*s.upper_bound(dfn[x]);
if (l!=-inf) ans+=(LL)t*dis(num[l],x);
if (r!=inf) ans+=(LL)t*dis(num[r],x);
if (l!=-inf && r!=inf) ans-=(LL)t*dis(num[l],num[r]);
if (s.size()>3) t=dis(num[*s.upper_bound(-inf)],num[*--s.lower_bound(inf)]);
else t=0;
printf("%lld\n",ans+t);
}
return 0;
}
【bzoj3991】 寻宝游戏的更多相关文章
- BZOJ3991 寻宝游戏 LCA 虚树 SET
5.26 T1:寻宝游戏 Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄, ...
- [Bzoj3991]寻宝游戏(dfs序+set)
Description 题目链接 Solution 用set按dfs序维护当前的宝物序列,那么答案为相邻2个点的距离加上头尾2个的距离 Code #include <cstdio> #in ...
- [BZOJ3991][SDOI2015]寻宝游戏
[BZOJ3991][SDOI2015]寻宝游戏 试题描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择 ...
- 【BZOJ3991】寻宝游戏(动态规划)
[BZOJ3991]寻宝游戏(动态规划) 题面 BZOJ 题解 很明显,从任意一个有宝藏的点开始,每次走到相邻的\(dfs\)的节点就行了. 证明? 类似把一棵树上的关键点全部标记出来 显然是要走一个 ...
- 【BZOJ3991】[SDOI2015]寻宝游戏 树链的并+set
[BZOJ3991][SDOI2015]寻宝游戏 Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩 ...
- [bzoj3991][SDOI2015]寻宝游戏_树链的并_倍增lca_平衡树set
寻宝游戏 bzoj-3991 SDOI-2015 题目大意:题目链接. 注释:略. 想法:我们发现如果给定了一些点有宝物的话那么答案就是树链的并. 树链的并的求法就是把所有点按照$dfs$序排序然后相 ...
- 【BZOJ3991】【SDOI2015】寻宝游戏
Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然 ...
- CH#56C 异象石 和 BZOJ3991 [SDOI2015]寻宝游戏
异象石 CH Round #56 - 国庆节欢乐赛 描述 Adera是Microsoft应用商店中的一款解谜游戏. 异象石是进入Adera中异时空的引导物,在Adera的异时空中有一张地图.这张地图上 ...
- BZOJ3991:寻宝游戏 (LCA+dfs序+树链求并+set)
小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路上行走 ...
- BZOJ3991 [SDOI2015]寻宝游戏 【dfs序 + lca + STL】
题目 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路 ...
随机推荐
- PAT 1003. 我要通过!(20) JAVA
参考http://blog.csdn.net/bin8632/article/details/50216297 答案正确"是自动判题系统给出的最令人欢喜的回复.本题属于PAT的"答 ...
- 02传智_jbpm与OA项目_部门模块
部门模块:具有增删改查(部门)的功能. Dao层的实现: 1,定义一个DepartmentDao.java. 定义基本的数据库操作.
- Caffe学习系列(23):如何将别人训练好的model用到自己的数据上
caffe团队用imagenet图片进行训练,迭代30多万次,训练出来一个model.这个model将图片分为1000类,应该是目前为止最好的图片分类model了. 假设我现在有一些自己的图片想进行分 ...
- 如何在前台脚本通过json传递数据到后台(使用微软自带的ajax)
首先,我们要在前台引入json的脚本,以便于把js对象序列化 <script type="text/javascript" src="/js/jquery.json ...
- PHP 对于 MYSQL 基础操作
基础 <?php // 不打印 notice info // error_reporting(0); // 连接 mysql $con = mysql_connect("localho ...
- parsing XML document from class path resource
遇到问题:parsing XML document from class path resource [spring/resources] 解决方法:项目properties— source—remo ...
- (译文)MVC通用仓储类
Generic Repository Pattern MVC Generic Repository Pattern MVC 原文链接:http://www.codeproject.com/Articl ...
- variable-precision SWAR算法介绍
BITCOUNT命令是统计一个位数组中非0进制位的数量,数学上称作:”Hanmming Weight“ 目前效率最好的为variable-precision SWAR算法,可以常数时间内计算出多个字节 ...
- 深入grootJs(进阶教程)
深入grootJs 这篇教程的原则是把grootJs原理讲透,主要真正理解了原理才能用起来随心所欲 mvvm模式简介 grootJs的vm结构 扫描函数sweep 垃圾回收的原理 加载器中的预编 ,控 ...
- Bootstrap系列 -- 9. 表格
一. Bootstrap 表格样式支持 Bootstrap提供了六种不同风格的样式支持,其中一个基础样式,4个附件样式,1个响应式设计样式 1. .table:基础表格 2. .table-strip ...