[洛谷P3320] SDOI2015 寻宝游戏
问题描述
小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达。游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的道路上行走,若走到某个村庄中有宝物,则视为找到该村庄内的宝物,直到找到所有宝物并返回到最初转移到的村庄为止。
小B希望评测一下这个游戏的难度,因此他需要知道玩家找到所有宝物需要行走的最短路程。但是这个游戏中宝物经常变化,有时某个村庄中会突然出现宝物,有时某个村庄内的宝物会突然消失,因此小B需要不断地更新数据,但是小B太懒了,不愿意自己计算,因此他向你求助。为了简化问题,我们认为最开始时所有村庄内均没有宝物
输入格式
第一行,两个整数N、M,其中M为宝物的变动次数。接下来的N-1行,每行三个整数x、y、z,表示村庄x、y之间有一条长度为z的道路。接下来的M行,每行一个整数t,表示一个宝物变动的操作。若该操作前村庄t内没有宝物,则操作后村庄内有宝物;若该操作前村庄t内有宝物,则操作后村庄内没有宝物。
输出格式
M行,每行一个整数,其中第i行的整数表示第i次操作之后玩家找到所有宝物需要行走的最短路程。若只有一个村庄内有宝物,或者所有村庄内都没有宝物,则输出0。
样例输入
4 5
1 2 30
2 3 50
2 4 60
2
3
4
2
1
样例输出
0
100
220
220
280
解析
手动模拟之后我们可以发现,对于一个已经确定哪些地方有宝藏的地图,无论从哪个地方出发的路径长度是一样的。稍加归纳我们可以发现,要求的答案就是
\]
其中\(p\)是按照DFS序排序后的宝藏地点数组。因此,我们可以用set维护所有有宝藏的地点序列,关键字为DFS序。每次插入都找到插入点在set中的前驱后继,然后用LCA求路径长度修改答案即可。
代码
#include <iostream>
#include <cstdio>
#include <set>
#include <cmath>
#define int long long
#define N 100002
using namespace std;
int head[N],ver[N*2],nxt[N*2],edge[N*2],l;
int n,m,i,f[N][20],dep[N],dfn[N],dis[N],tim;
bool vis[N];
struct node{
int p;
node(int _p){p=_p;}
bool operator < (const node &a) const{
return dfn[a.p]<dfn[p];
}
};
set<node> s;
set<node>::iterator it1,it2;
int read()
{
char c=getchar();
int w=0;
while(c<'0'||c>'9') c=getchar();
while(c<='9'&&c>='0'){
w=w*10+c-'0';
c=getchar();
}
return w;
}
void insert(int x,int y,int z)
{
l++;
ver[l]=y;
edge[l]=z;
nxt[l]=head[x];
head[x]=l;
}
void dfs(int x,int pre)
{
dfn[x]=++tim;
f[x][0]=pre;
dep[x]=dep[pre]+1;
for(int i=head[x];i;i=nxt[i]){
int y=ver[i];
if(y!=pre){
dis[y]=dis[x]+edge[i];
dfs(y,x);
}
}
}
void init()
{
dfs(1,0);
for(int j=0;(1<<(j+1))<=n;j++){
for(int i=1;i<=n;i++) f[i][j+1]=f[f[i][j]][j];
}
}
int LCA(int u,int v)
{
if(dep[u]>dep[v]) swap(u,v);
int tmp=dep[v]-dep[u];
for(int i=0;(1<<i)<=tmp;i++){
if((1<<i)&tmp) v=f[v][i];
}
if(u==v) return u;
for(int i=log2(1.0*n);i>=0;i--){
if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i];
}
return f[u][0];
}
int dist(int x,int y)
{
return dis[x]+dis[y]-2*dis[LCA(x,y)];
}
signed main()
{
n=read();m=read();
for(i=1;i<n;i++){
int u=read(),v=read(),w=read();
insert(u,v,w);
insert(v,u,w);
}
init();
int ans=0;
for(i=1;i<=m;i++){
int x=read();
if(vis[x]){
vis[x]=0;
if(s.size()!=1){
it1=it2=s.find(node(x));
if(it1==s.begin()) it1=s.end();
it1--;it2++;
if(it2==s.end()) it2=s.begin();
ans+=dist((*it1).p,(*it2).p)-dist(x,(*it1).p)-dist(x,(*it2).p);
}
s.erase(node(x));
}
else{
vis[x]=1;
s.insert(node(x));
if(s.size()!=1){
it1=it2=s.find(node(x));
if(it1==s.begin()) it1=s.end();
it1--;it2++;
if(it2==s.end()) it2=s.begin();
ans-=dist((*it1).p,(*it2).p)-dist(x,(*it1).p)-dist(x,(*it2).p);
}
}
printf("%lld\n",ans);
}
return 0;
}
[洛谷P3320] SDOI2015 寻宝游戏的更多相关文章
- [bzoj3991] [洛谷P3320] [SDOI2015] 寻宝游戏
Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有 \(N\) 个村庄和 \(N-1\) 条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬 ...
- 洛谷 P3320 [SDOI2015]寻宝游戏
因为寻宝路径是一个环,所以寻宝花费的最小时间与起点无关.宝应当按照所有宝藏所在位置的 dfs 序进行才能够使得花费的时间最短.设 \(dist_i\) 表示 \(i\) 到树根的最短距离,那么树上任意 ...
- 洛谷3320 SDOI2015寻宝游戏(set+dfs序)(反向迭代器的注意事项!)
被\(STL\)坑害了一个晚上,真的菜的没救了啊. 准确的说是一个叫\(reverse\ iterator\)的东西,就是我们经常用的\(rbegin()\) 有一个非常重要的性质 在反向迭代器中,+ ...
- P3320 [SDOI2015]寻宝游戏 解题报告
P3320 [SDOI2015]寻宝游戏 题目描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有\(N\)个村庄和\(N-1\)条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以 ...
- P3320 [SDOI2015]寻宝游戏
题目 P3320 [SDOI2015]寻宝游戏 做法 很巧妙的一种思路,懂了之后觉得大水题 首先要知道:在一棵树上标记一些点,然后从任意一点出发,遍历所有的的最小路径为\(dfs\)序从小到大遍历 那 ...
- Luogu P3320 [SDOI2015]寻宝游戏 / 异象石 【LCA/set】
期末考试结束祭! 在期末考试前最后一发的测试中,异象石作为第二道题目出现QAQ.虽然知道是LCA图论,但还是敲不出来QAQ. 花了两天竞赛课的时间搞懂(逃 异象石(stone.pas/c/cpp)题目 ...
- luogu P3320 [SDOI2015]寻宝游戏
大意:给定树, 要求维护一个集合, 支持增删点, 询问从集合中任取一点作为起点, 遍历完其他点后原路返回的最短长度. 集合中的点按$dfs$序排列后, 最短距离就为$dis(s_1,s_2)+...+ ...
- 【LG3320】[SDOI2015]寻宝游戏
[LG3320][SDOI2015]寻宝游戏 题面 洛谷 题解 不需要建虚树的虚树2333... 贪心地想一下,起始节点肯定是在关键点上,访问顺序就是\(dfs\)序. 那么对于每次询问, \[ An ...
- [BZOJ3991][SDOI2015]寻宝游戏
[BZOJ3991][SDOI2015]寻宝游戏 试题描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择 ...
随机推荐
- 【HTML5】---【HTML5提供的一些新的标签用法以及和HTML 4的区别】
HTML 5 是一个新的网络标准,目标在于取代现有的 HTML 4.01, XHTML 1.0 and DOM Level 2 HTML 标准.它希望能够减少浏览器对于需要插件的丰富性网络应用服务(p ...
- Django 中 ModelForm 的使用
定义 ModelForm 定制 ModelForm Meta 在 Form 中另外定义 Field 值得一提的一些 Field 转化 AutoField BooleanField ForeignKey ...
- SpringCloud常用注解有哪些?
@Mapper: 注解写在你的Mapper映射接口上面 @SpringBootApplication: 写在主程序上面 @Configuration: 写在配置类上面 @Bean: 写在配置类中的返回 ...
- P3367 【模板】并查集
喵呜~~(题面) 这题其实很早就过了,但是呢,以前过的时候真的基本上是CtrlC+CtrlV,这次把代码重新码了一遍,对并查集也有了一个基本清晰的认识 #include<iostream> ...
- 关于DataFram的.values
DataFram类型的变量a,设a有n个样本,m个特征,当执行语句b = a.values后,b为(n, m)的ndarray矩阵类型,当执行c = b.ravel()后,c为(n*m,)维行向量
- 《Python编程从0到1》笔记1——表达式的风格(前缀、中缀、后缀)
运算符和运算数组成表达式.运算符和运算数的出现次序会影响表达式乃至程序设计语言的风格. 1.前缀表达式 前缀,是指运算符的位置在前.前缀风格的一个例子是函数调用,如求最大值函数:max(3, 2, 5 ...
- HDU 1069 Monkey and Banana (动态规划、上升子序列最大和)
Monkey and Banana Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- CentOS7之SVN服务配置
操作系统:CentOS Linux release 7.2.1511 (Core) Subversion软件版本:subversion-1.7.14-10.el7.x86_64 1.首先检查sv ...
- Virtual DOM和snabbdom.js
Virtual DOM和snabbdom.js:https://www.jianshu.com/p/1f1ef915e83e
- SpringBoot_02通用mapper
注意:一旦引入了通用Mapper的启动器,会覆盖Mybatis官方启动器的功能,因此需要移除对官方Mybatis启动器的依赖. 无需任何配置就可以使用了.如果有特殊需要,可以到通用mapper官网查看 ...