洛谷 P3320 [SDOI2015]寻宝游戏
因为寻宝路径是一个环,所以寻宝花费的最小时间与起点无关。宝应当按照所有宝藏所在位置的 dfs 序进行才能够使得花费的时间最短。设 \(dist_i\) 表示 \(i\) 到树根的最短距离,那么树上任意两点 \(i\,,j\) 的最短距离就是 \(d_{i,j} = dist_i + dist_j - 2 \times dist_{\operatorname{lca}(i, j)}\)。这样,寻宝的环的长度就可以表示为 \(\sum_{i=1}^cd_{i,\operatorname{next}(i)}\)(\(c\) 是宝藏数量,\(\operatorname{next}(i) =
\begin{cases}
i+1,& i < c\\
1,& i = c
\end{cases}\)) 了。
添加删除宝藏都可以用 std::set 来很方便地维护。
#include <cstdio>
#include <set>
#include <algorithm>
const int MAXN = 1e5 + 19;
struct Edge{
int to, next, dist;
}edge[MAXN << 1];
int cnt, head[MAXN];
inline void add(int from, int to, int dist){
edge[++cnt].to = to;
edge[cnt].dist = dist;
edge[cnt].next = head[from];
head[from] = cnt;
}
int dfn[MAXN], id[MAXN], t;
int dep[MAXN], fa[MAXN][20];
long long dist[MAXN], ans;
void dfs(int node, int f){
dfn[node] = ++t;
dep[node] = dep[f] + 1;
id[t] = node;
fa[node][0] = f;
for(int i = 1; (1 << i) < dep[node]; ++i)
fa[node][i] = fa[fa[node][i - 1]][i - 1];
for(int i = head[node]; i; i = edge[i].next)
if(edge[i].to != f)
dist[edge[i].to] = dist[node] + edge[i].dist, dfs(edge[i].to, node);
}
int lca(int x, int y){
if(dep[x] < dep[y])
std::swap(x, y);
for(int i = dep[x] - dep[y], j = 0; i; i >>= 1, ++j)
if(i & 1)
x = fa[x][j];
if(x == y)
return x;
for(int i = 18; i >= 0; --i)
if(fa[x][i] != fa[y][i])
x = fa[x][i], y = fa[y][i];
return fa[x][0];
}
inline long long time(int a, int b){
return dist[a] + dist[b] - 2ll * dist[lca(a, b)];
}
int n, m;
bool vist[MAXN];
std::set<int>s;
std::set<int>::iterator it;
int main(){
std::scanf("%d%d", &n, &m);
for(int u, v, c, i = 1; i < n; ++i)
std::scanf("%d%d%d", &u, &v, &c), add(u, v, c), add(v, u, c);
dfs(1, 0);
while(m--){
int a, b;
std::scanf("%d", &t);
if(!vist[t])
s.insert(dfn[t]);
a = id[*((it = s.lower_bound(dfn[t])) == s.begin() ? --s.end() : --it)];
b = id[*((it = s.lower_bound(dfn[t]), ++it) == s.end() ? s.begin() : it)];
if(vist[t])
s.erase(dfn[t]);
long long d = time(a, t) + time(b, t) - time(a, b);
if(vist[t])
ans -= d;
else
ans += d;
vist[t] ^= 1;
std::printf("%lld\n", ans);
}
return 0;
}
第一次接触 dfs 序和树上最小距离......要尽早把与树相关的知识点学了啊。
洛谷 P3320 [SDOI2015]寻宝游戏的更多相关文章
- [洛谷P3320] SDOI2015 寻宝游戏
问题描述 小B最近正在玩一个寻宝游戏,这个游戏的地图中有N个村庄和N-1条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬间转移到这个村庄,然后可以任意在地图的 ...
- [bzoj3991] [洛谷P3320] [SDOI2015] 寻宝游戏
Description 小B最近正在玩一个寻宝游戏,这个游戏的地图中有 \(N\) 个村庄和 \(N-1\) 条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择一个村庄,瞬 ...
- 洛谷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条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择 ...
随机推荐
- 【C语言】无参函数调用实例
#include<stdio.h> void hello() { printf("年轻人,加油!"); } int main() { hello(); ; }
- Deeplearning.ai课程笔记-结构化机器学习项目
目录 一. 正交化 二. 指标 1. 单一数字评估指标 2. 优化指标.满足指标 三. 训练集.验证集.测试集 1. 数据集划分 2. 验证集.测试集分布 3. 验证集.测试集大小 四. 比较人类表现 ...
- 使用阿里的EasyExcel遇到的一些坑(NoSuchMethodError异常)
引入eayexcel依赖的时候已经包含了poi依赖
- Java中引用类型、对象的创建与销毁
引用类型 在java中,除了基本数据类型之外的,就是引用数据类型了,引用指的是对象的一个引用,通过引用可以操作对象,控制对象,向对象发送消息. 简单来说,引用可以访问对象的属性,并调用对象的方法 创建 ...
- 吴裕雄--天生自然TensorFlow2教程:反向传播算法
- 吴裕雄 python 神经网络——TensorFlow TFRecord样例程序
import numpy as np import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_dat ...
- 【原】Docker学习_Docker上传镜像至docker hub(4)
构造镜像的两种方式:1.commit 2.Dockerfile Docker提供了一个docker commit命令,可以将容器的存储层保存下来成为镜像.换句话说,就是在原有镜像的基础上,再叠加上容 ...
- leetcode: 0204 完成的
目录 大纲:0204 完成的 notes ✅1051 高度检查器 ✅ 728 自除数 brute c解答: java switch 语句 java api: array 直接有 length 属性 , ...
- 【PAT甲级】1039 Course List for Student (25 分)(vector嵌套于map,段错误原因未知)
题意: 输入两个正整数N和K(N<=40000,K<=2500),分别为学生和课程的数量.接下来输入K门课的信息,先输入每门课的ID再输入有多少学生选了这门课,接下来输入学生们的ID.最后 ...
- 一、FreeMarker实现对js和css压缩
1.代码压缩理解:实际上就是将原有的文本中无用的注释.空行.空格去掉来压缩文件的大小.进行js和css压缩会带来如下好处:1)减小了文件的体积,减少文件占用的内存;2)减小了网络传输量和带宽占用; 3 ...