洛谷 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条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择 ...
随机推荐
- angular常用命令整理
1.创建项目 ng new 命令 描述ng new <project-name> [options] 创建一个新的 Angular 项目,默认在当前所在目录下参数 描述--dry-run ...
- springboot笔记-1.自动化配置的关键
最近发现看过的东西容易忘,但是写一遍之后印象倒是会深刻的多. 总所周知springboot极大的简化了java开发繁琐性,而其最大的优势应该就是自动化配置了.比如要使用redis,我们直接引入相关的包 ...
- 17,a:img的alt和title有何异同? b:strong与en的异同?
alt(alt text):为不能显示的图像,窗体或者applets的用户代理,alt属性用来指定替换文字.替换文字的语言用lang属性来指定. eg:下例中将图像作为链接来使用 <a href ...
- rsync+inotify实现主机之间目录实时同步
原理: rsync:用于跨主机目录同步 inotify:用于监测目录变化 再编写一个触发脚本,一旦inotify检测到目录中内容发生变化,则调用rsync执行同步. rsync服务器的的配置: 因为r ...
- C#加密解密(AES)-AESHelper
原文地址:https://ken.io/note/csharp-aesencrypt using System; namespace Encrypt { public class AESHelper ...
- 【代码总结】数据库抽象层PDO
一.概述 PDO就是一个"数据库访问抽象层",起作用是统一各种数据库的访问接口,能够轻松的在不同数据库之间进行切换. 二.PDO的安装 编辑php.ini文件 添加 extensi ...
- USER 指定当前用户,希望以某个已经建立好的用户来运行某个服务进程,不要使用 su 或者 sudo,这些都需要比较麻烦的配置,而且在 TTY 缺失的环境下经常出错。建议使用 gosu
USER 指定当前用户 格式:USER <用户名>[:<用户组>] USER 指令和 WORKDIR 相似,都是改变环境状态并影响以后的层.WORKDIR 是改变工作目录,US ...
- spring boot 配置时区差别
前提 数据库时区:GMT+8 show variables like '%time_zone%'; 本机电脑时区: 情景一.不指定时区 传递的参数映射到Data不指定时区,连接数据库不指定时区,保存时 ...
- 十八、sun JPA理解及使用
1.JPA理解及实现: JPA(Java Persistence API)作为Java EE 5.0平台标准的ORM规范,将得到所有Java EE服务器的支持,是SUN在充分吸收现有ORM框架的 ...
- Linux查看当前系统32位还是64位
getconf LONG_BIT 此方法会直接返回32或64