[NOI2018]归程 kruskal重构树
[NOI2018]归程
kruskal重构树模板题。
另一篇文章里有关于kruskal重构树更详细的介绍和更板子的题目。
题意懒得说了,这题的关键在于快速找出从查询的点出发能到达的点(即经过海拔高于水位线的边能到达的点)中距离\(1\)号点最近的距离。
看上去可以kruskal,假设我们把边实现按海拔从大到小排序,考虑我们的重构树的性质:一个小根堆,任意一个点到根节点的路径上的点权单调不升,且这条路径上最浅的高于水位线的点\(u\)的子树中的所有叶节点就是这个点所能到达的所有点。dijkstra预处理每个点到\(1\)的最短路,再在重构树上一遍dfs处理出每棵子树中到\(1\)的最短距离,查询时\(u\)直接倍增求,这题就做完了。
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#include <queue>
#define R register
#define I inline
#define B 1000000
using namespace std;
const int N = 200003, M = 400003, inf = 2e9;
char buf[B], *p1, *p2;
I char gc() { return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, B, stdin), p1 == p2) ? EOF : *p1++; }
I int rd() {
R int f = 0;
R char c = gc();
while (c < 48 || c > 57)
c = gc();
while (c > 47 && c < 58)
f = f * 10 + (c ^ 48), c = gc();
return f;
}
int s[N], vis[N], dis[N], f[M], o[M], val[M], son[M][2], dep[M], fa[M][20], n, cnt;
struct edge { int u, v, l, a; }e[M];
vector <pair <int, int> > g[N];
priority_queue <pair <int, int> > q;
I int operator < (edge x, edge y) { return x.a > y.a; }
I int min(int x, int y) { return x < y ? x : y; }
I int find(int x) {
R int r = x, y;
while (f[r] ^ r)
r = f[r];
while (x ^ r)
y = f[x], f[x] = r, x = y;
return r;
}
void dfs(int x, int f) {
dep[x] = dep[f] + 1, fa[x][0] = f;
for (R int i = 1; i < 20; ++i)
fa[x][i] = fa[fa[x][i - 1]][i - 1];
if (x <= n) {
o[x] = dis[x];
return ;
}
dfs(son[x][0], x), dfs(son[x][1], x), o[x] = min(o[son[x][0]], o[son[x][1]]);
}
I int query(int x, int y) {
for (R int i = 19; ~i; --i)
if (dep[x] - (1 << i) > 0 && val[fa[x][i]] > y)
x = fa[x][i];
return o[x];
}
int main() {
R int T = rd(), m, Q, K, S, i, x, y, z, last;
while (T--) {
memset(vis, 0, sizeof vis), n = rd(), m = rd(), last = 0;
for (i = 1; i <= n; ++i)
g[i].clear();
for (i = 1; i <= m; ++i) {
x =rd(), y = rd(), z =rd(), e[i] = (edge){x, y, z, rd()};
g[x].push_back(make_pair(y, z)), g[y].push_back(make_pair(x, z));
}
for (i = 1; i <= n; ++i)
s[i] = g[i].size(), dis[i] = inf;
for (i = 1; i < n << 1; ++i)
f[i] = i;
dis[1] = 0, q.push(make_pair(0, 1));
while (!q.empty()) {
x = q.top().second, q.pop();
if (vis[x])
continue;
vis[x] = 1;
for (i = 0; i < s[x]; ++i) {
y = g[x][i].first, z = g[x][i].second;
if (dis[y] > dis[x] + z)
dis[y] = dis[x] + z, q.push(make_pair(-dis[y], y));
}
}
sort(e + 1, e + m + 1), cnt = n;
for (i = 1; i <= m; ++i) {
x = find(e[i].u), y = find(e[i].v);
if (x ^ y) {
++cnt, f[x] = f[y] = cnt, val[cnt] = e[i].a;
son[cnt][0] = x, son[cnt][1] = y;
}
}
dfs(cnt, 0), Q = rd(), K = rd(), S = rd();
for (i = 1; i <= Q; ++i) {
x = (rd() + K * last - 1) % n + 1, y = (rd() + K * last) % (S + 1);
printf("%d\n", last = query(x, y));
}
}
return 0;
}
[NOI2018]归程 kruskal重构树的更多相关文章
- [洛谷P4768] [NOI2018]归程 (kruskal重构树模板讲解)
洛谷题目链接:[NOI2018]归程 因为题面复制过来有点炸格式,所以要看题目就点一下链接吧\(qwq\) 题意: 在一张无向图上,每一条边都有一个长度和海拔高度,小\(Y\)的家在\(1\)节点,并 ...
- BZOJ5415[Noi2018]归程——kruskal重构树+倍增+堆优化dijkstra
题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n).我们依次用 l,a 描述一条边的长度.海 ...
- BZOJ 5415: [Noi2018]归程(kruskal重构树)
解题思路 \(NOI2018\)的\(Day1\) \(T1\),当时打网络赛的时候不会做.学了一下\(kruskal\)重构树后发现问题迎刃而解了.根据\(kruskal\)的性质,如果要找从\(u ...
- 洛谷P4768 [NOI2018]归程(Kruskal重构树)
题意 直接看题目吧,不好描述 Sol 考虑暴力做法 首先预处理出从$1$到每个节点的最短路, 对于每次询问,暴力的从这个点BFS,从能走到的点里面取$min$ 考虑如何优化,这里要用到Kruskal重 ...
- LOJ.2718.[NOI2018]归程(Kruskal重构树 倍增)
LOJ2718 BZOJ5415 洛谷P4768 Rank3+Rank1无压力 BZOJ最初还不是一道权限题... Update 2019.1.5 UOJ上被hack了....好像是纯一条链的数据过不 ...
- BZOJ_5415_[Noi2018]归程_kruscal重构树+倍增+最短路
BZOJ_5415_[Noi2018]归程_kruscal重构树+倍增 Description www.lydsy.com/JudgeOnline/upload/noi2018day1.pdf 好久不 ...
- NOI Day1T1归程(Kruskal重构树+Dijkstra)
NOI Day1T1归程(Kruskal重构树+Dijkstra) 题目 洛谷题目传送门 题解 其实我不想写......,所以...... 挖个坑......我以后一定会补的 luogu的题解讲的还是 ...
- #2718. 「NOI2018」归程 kruskal重构树
链接 https://loj.ac/problem/2718 思路 我们希望x所在的连通块尽量的大,而且尽量走高处 离线的话可以询问排序,kruskal过程中更新答案 在线就要用kruskal重构树 ...
- loj2718 「NOI2018」归程[Kruskal重构树+最短路]
关于Kruskal重构树可以翻阅本人的最小生成树笔记. 这题明显裸的Kruskal重构树. 然后这题限制$\le p$的边不能走,实际上就是要满足走最小边权最大的瓶颈路,于是跑最大生成树,构建Krus ...
随机推荐
- 解析UIControl
解析UIControl 从下图可以看出,UIControl继承自UIView,添加了响应事件功能. UIButton之所以能响应各种各样的事件是因为继承自UIControl 使用UIControl可以 ...
- DPM恢复点和保持期、常见问题排除指南
“恢复点计划”确定应为该保护组创建多少个恢复点. 对于文件保护,选择希望创建恢复点的日期和时间. 对于支持增量备份的应用程序数据保护,同步频率决定了恢复点计划. 对于不支持增量备份的应用程序数据保护, ...
- UNIX高级环境编程(3)Files And Directories - stat函数,文件类型,和各种ID
在前面的两篇,我们了解了IO操作的一些基本操作函数,包括open.read和write. 在本篇我们来学习一下文件系统的其他特性和一个文件的属性,涉及的函数功能包括: 查看文件的所有属性: 改变文件所 ...
- Linux uname命令详解
uname常见命令参数 -a, --all print all information, in the following order, except omit -p and -i if unknow ...
- AltiumDesigner17学习指南
AltiumDesigner工程模板 工程文件管理 视图->桌面布局->默认 恢复界面 AltiumDesigner17功能 修改元件标号 双击元件标号,在Designetor的Value ...
- THE CUP OF LIFE即生命之杯。
生命之杯 编辑 THE CUP OF LIFE即生命之杯. <生命之杯>(西班牙语:La copa de la vida,英语:The Cup of Life)是一首由波多黎各裔歌手瑞奇· ...
- ZT 二叉树先序,中序,后序遍历非递归实现
二叉树先序,中序,后序遍历非递归实现 分类: 数据结构及算法2012-04-28 14:30 8572人阅读 评论(6) 收藏 举报 structc 利用栈实现二叉树的先序,中序,后序遍历的非递归操作 ...
- DevExpress01、独立使用的控件
XtraEditors 库提供了只能独立使用的控件,也就是说不能在容器控件的内置编辑中使用它们. 这些控件包括: 几种类型的列表框.数据导航控件.滚动条和一个按钮控件. 这些控件都是 BaseStyl ...
- CSS3 Transform变形理解与应用
CSS3 Transform变形理解与应用 Transform:对元素进行变形:Transition:对元素某个属性或多个属性的变化,进行控制(时间等),类似flash的补间动画.但只有两个关键贞.开 ...
- 关于elasticsearch 6.x及其插件head安装(单机与集群)5分钟解决
第一步,下载es6 +head wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.3.2.zip wg ...