[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 ...
随机推荐
- 要提高SQL查询效率where语句条件的先后次序应如何写
我们要做到不但会写SQL,还要做到写出性能优良的SQL语句. (1)选择最有效率的表名顺序(只在基于规则的优化器中有效): Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句 ...
- RHEL7:如何配置I / O调度程序
介绍 I / O调度程序用于优化磁盘上的读/写. RHEL 7中有三种类型的I / O调度程序(也称为I / O电梯): CFQ(C fullly F air Q ueuing)促进来自实时流程的I ...
- WinForm 应用程序禁止多个进程运行
方法一: 禁止多个进程运行 using System; using System.Collections.Generic; using System.Linq; using System.Window ...
- VUE入门准备------>ES6
声明变量的方式: var let const let 和 var的区别 var定义的变量是全局的会覆盖全局的定义 ; ;i<;i++){ console.log(i) } undefi ...
- 用block将UIAlertView与UIActionSheet统一起来
用block将UIAlertView与UIActionSheet统一起来 效果 1. 将代理方法的实例对象方法转换成了类方法使用 2. 要注意单例block不要长期持有,用完就释放掉 源码 https ...
- UINavigationController与UITabBarController相关问题
UINavigationController与UITabBarController相关问题 UINavigationController与UITabBarController混用是非常常见的,有时候会 ...
- 模板(template)包含与继承
Django 模板查找机制: Django 查找模板的过程是在每个 app 的 templates 文件夹中找(而不只是当前 app 中的代码只在当前的 app 的 templates 文件夹中找). ...
- python2.7下同步华为云照片的爬虫程序实现
1.背景 随着华为手机的销量加大,华为云的捆绑服务使用量也越来越广泛,华为云支持自动同步照片.通讯录.记事本等,用着确实也挺方便的,云服务带来方便的同时,也带来了数据管理风险.华为目前只提供一个www ...
- Linux fsck命令详解
fsck(file system check)用来检查和维护不一致的文件系统.若系统掉电或磁盘发生问题,可利用fsck命令对文件系统进行检查. fsck常见命令参数 -a:自动修复文件系统,不询问任何 ...
- November 15th 2016 Week 47th Tuesday
Success is finding satisfaction in giving a little more than you take. 成功就是付出比得到多,仍然心满意足. Can I find ...