洛谷 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条道路,并且任何两个村庄之间有且仅有一条路径可达.游戏开始时,玩家可以任意选择 ...
随机推荐
- Springboot项目搭建(1)-创建,整合mysql/oracle,druid配置,简单的CRUD
源码地址:https://github.com/VioletSY/article-base 1:创建一个基本项目:https://blog.csdn.net/mousede/article/detai ...
- springboot多模块项目打war包
一.父模块配置 1,指定pakaging:pom 2,指定编译的版本:如下图: <properties> <project.build.sourceEncoding>UTF-8 ...
- SpringCloud全家桶学习之分布式配置中心----Config(七)
一.概述 (1)背景 微服务意味着将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中出现大量的服务.由于每个服务都需要配置必要的配置信息才能运行,所以一套集中式的.动态的配置管理 ...
- 「JSOI2015」salesman
「JSOI2015」salesman 传送门 显然我们为了使收益最大化就直接从子树中选大的就好了. 到达次数的限制就是限制了可以选的子树的数量,因为每次回溯上来都会减一次到达次数. 多种方案的判断就是 ...
- jq 常用语句
//jq post 请求 $.post("demo_ajax_gethint.asp",{suggest:txt},function(result){ }); // jq get ...
- DAY1小题
F 求逆序对的板子题 #include<cstdio> #define ll long long using namespace std; ; ll a[maxn],r[maxn],n; ...
- 例题3_3 回文词(UVa401)
输入一个字符串,判断它是否为回文串以及镜像串.输入字符串保证不含数字0.所谓回文串,就是反转以后和原串相同,如abba和madam.所有镜像串,就是左右镜像之后和原串相同,如2S和3AIAE.注意,并 ...
- java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time.....
SpringBoot 2.1.4启动时报错 java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecogniz ...
- Python数据分析之Numpy操作大全
从头到尾都是手码的,文中的所有示例也都是在Pycharm中运行过的,自己整理笔记的最大好处在于可以按照自己的思路来构建矿建,等到将来在需要的时候能够以最快的速度看懂并应用=_= 注:为方便表述,本章设 ...
- SVN中如何创建共享文件夹
http://wenku.baidu.com/link?url=E8tC1idSdTABc3JzyqGYF8OXakDTIF_yWp8BvFqSX5dgcpkbm8Z57ursZtLpjmQAEABM ...