[NOI2018]归程

LG传送门

kruskal重构树模板题。

另一篇文章里有关于kruskal重构树更详细的介绍和更板子的题目。

题意懒得说了,这题的关键在于快速找出从查询的点出发能到达的点(即经过海拔高于水位线的边能到达的点)中距离\(1\)号点最近的距离。

看上去可以kruskal,假设我们把边实现按海拔从大到小排序,考虑我们的重构树的性质:一个小根堆,任意一个点到根节点的路径上的点权单调不升,且这条路径上最浅的高于水位线的点\(u\)的子树中的所有叶节点就是这个点所能到达的所有点。dijkstra预处理每个点到\(1\)的最短路,再在重构树上一遍dfs处理出每棵子树中到\(1\)的最短距离,查询时\(u\)直接倍增求,这题就做完了。

  1. #include <cstdio>
  2. #include <cctype>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <queue>
  6. #define R register
  7. #define I inline
  8. #define B 1000000
  9. using namespace std;
  10. const int N = 200003, M = 400003, inf = 2e9;
  11. char buf[B], *p1, *p2;
  12. I char gc() { return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, B, stdin), p1 == p2) ? EOF : *p1++; }
  13. I int rd() {
  14. R int f = 0;
  15. R char c = gc();
  16. while (c < 48 || c > 57)
  17. c = gc();
  18. while (c > 47 && c < 58)
  19. f = f * 10 + (c ^ 48), c = gc();
  20. return f;
  21. }
  22. int s[N], vis[N], dis[N], f[M], o[M], val[M], son[M][2], dep[M], fa[M][20], n, cnt;
  23. struct edge { int u, v, l, a; }e[M];
  24. vector <pair <int, int> > g[N];
  25. priority_queue <pair <int, int> > q;
  26. I int operator < (edge x, edge y) { return x.a > y.a; }
  27. I int min(int x, int y) { return x < y ? x : y; }
  28. I int find(int x) {
  29. R int r = x, y;
  30. while (f[r] ^ r)
  31. r = f[r];
  32. while (x ^ r)
  33. y = f[x], f[x] = r, x = y;
  34. return r;
  35. }
  36. void dfs(int x, int f) {
  37. dep[x] = dep[f] + 1, fa[x][0] = f;
  38. for (R int i = 1; i < 20; ++i)
  39. fa[x][i] = fa[fa[x][i - 1]][i - 1];
  40. if (x <= n) {
  41. o[x] = dis[x];
  42. return ;
  43. }
  44. dfs(son[x][0], x), dfs(son[x][1], x), o[x] = min(o[son[x][0]], o[son[x][1]]);
  45. }
  46. I int query(int x, int y) {
  47. for (R int i = 19; ~i; --i)
  48. if (dep[x] - (1 << i) > 0 && val[fa[x][i]] > y)
  49. x = fa[x][i];
  50. return o[x];
  51. }
  52. int main() {
  53. R int T = rd(), m, Q, K, S, i, x, y, z, last;
  54. while (T--) {
  55. memset(vis, 0, sizeof vis), n = rd(), m = rd(), last = 0;
  56. for (i = 1; i <= n; ++i)
  57. g[i].clear();
  58. for (i = 1; i <= m; ++i) {
  59. x =rd(), y = rd(), z =rd(), e[i] = (edge){x, y, z, rd()};
  60. g[x].push_back(make_pair(y, z)), g[y].push_back(make_pair(x, z));
  61. }
  62. for (i = 1; i <= n; ++i)
  63. s[i] = g[i].size(), dis[i] = inf;
  64. for (i = 1; i < n << 1; ++i)
  65. f[i] = i;
  66. dis[1] = 0, q.push(make_pair(0, 1));
  67. while (!q.empty()) {
  68. x = q.top().second, q.pop();
  69. if (vis[x])
  70. continue;
  71. vis[x] = 1;
  72. for (i = 0; i < s[x]; ++i) {
  73. y = g[x][i].first, z = g[x][i].second;
  74. if (dis[y] > dis[x] + z)
  75. dis[y] = dis[x] + z, q.push(make_pair(-dis[y], y));
  76. }
  77. }
  78. sort(e + 1, e + m + 1), cnt = n;
  79. for (i = 1; i <= m; ++i) {
  80. x = find(e[i].u), y = find(e[i].v);
  81. if (x ^ y) {
  82. ++cnt, f[x] = f[y] = cnt, val[cnt] = e[i].a;
  83. son[cnt][0] = x, son[cnt][1] = y;
  84. }
  85. }
  86. dfs(cnt, 0), Q = rd(), K = rd(), S = rd();
  87. for (i = 1; i <= Q; ++i) {
  88. x = (rd() + K * last - 1) % n + 1, y = (rd() + K * last) % (S + 1);
  89. printf("%d\n", last = query(x, y));
  90. }
  91. }
  92. return 0;
  93. }

[NOI2018]归程 kruskal重构树的更多相关文章

  1. [洛谷P4768] [NOI2018]归程 (kruskal重构树模板讲解)

    洛谷题目链接:[NOI2018]归程 因为题面复制过来有点炸格式,所以要看题目就点一下链接吧\(qwq\) 题意: 在一张无向图上,每一条边都有一个长度和海拔高度,小\(Y\)的家在\(1\)节点,并 ...

  2. BZOJ5415[Noi2018]归程——kruskal重构树+倍增+堆优化dijkstra

    题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 n 个节点.m 条边的无向连通图(节点的编号从 1 至 n).我们依次用 l,a 描述一条边的长度.海 ...

  3. BZOJ 5415: [Noi2018]归程(kruskal重构树)

    解题思路 \(NOI2018\)的\(Day1\) \(T1\),当时打网络赛的时候不会做.学了一下\(kruskal\)重构树后发现问题迎刃而解了.根据\(kruskal\)的性质,如果要找从\(u ...

  4. 洛谷P4768 [NOI2018]归程(Kruskal重构树)

    题意 直接看题目吧,不好描述 Sol 考虑暴力做法 首先预处理出从$1$到每个节点的最短路, 对于每次询问,暴力的从这个点BFS,从能走到的点里面取$min$ 考虑如何优化,这里要用到Kruskal重 ...

  5. LOJ.2718.[NOI2018]归程(Kruskal重构树 倍增)

    LOJ2718 BZOJ5415 洛谷P4768 Rank3+Rank1无压力 BZOJ最初还不是一道权限题... Update 2019.1.5 UOJ上被hack了....好像是纯一条链的数据过不 ...

  6. BZOJ_5415_[Noi2018]归程_kruscal重构树+倍增+最短路

    BZOJ_5415_[Noi2018]归程_kruscal重构树+倍增 Description www.lydsy.com/JudgeOnline/upload/noi2018day1.pdf 好久不 ...

  7. NOI Day1T1归程(Kruskal重构树+Dijkstra)

    NOI Day1T1归程(Kruskal重构树+Dijkstra) 题目 洛谷题目传送门 题解 其实我不想写......,所以...... 挖个坑......我以后一定会补的 luogu的题解讲的还是 ...

  8. #2718. 「NOI2018」归程 kruskal重构树

    链接 https://loj.ac/problem/2718 思路 我们希望x所在的连通块尽量的大,而且尽量走高处 离线的话可以询问排序,kruskal过程中更新答案 在线就要用kruskal重构树 ...

  9. loj2718 「NOI2018」归程[Kruskal重构树+最短路]

    关于Kruskal重构树可以翻阅本人的最小生成树笔记. 这题明显裸的Kruskal重构树. 然后这题限制$\le p$的边不能走,实际上就是要满足走最小边权最大的瓶颈路,于是跑最大生成树,构建Krus ...

随机推荐

  1. 从零开始导入gradle项目

    需要jdk1.8,idea17以上,电脑安装gradle(配置环境变量,与配置java类似),用git的push命令下项目,开始操作 gradle配置本地仓库位置:添加环境变量GRADLE_USER_ ...

  2. 重置 Winsock:初始化计算机网络环境

    初始化网络环境,以解决由于软件冲突.病毒原因造成的参数错误问题(复杂网络环境下慎用).批处理代码: netsh winhttp reset proxy netsh winhttp reset trac ...

  3. 铁乐学python_day03-作业

    1.有变量name = "aleX leNb" 完成如下操作: 移除name变量对应的值两边的空格,并输出处理结果 n1 = name.strip() print(n1) 结果:a ...

  4. C++ 读书笔记2

    dfadsfa body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding ...

  5. September 29th 2017 Week 39th Friday

    Human life is ephemera, which makes it precious. 生命短暂,所以珍贵. Don't waste time on praying to the God. ...

  6. Data Compression

    数据压缩 introduction 压缩数据可以节省存储数据需要的空间和传输数据需要的时间,虽然摩尔定律说集成芯片上的晶体管每 18-24 个月翻一倍,帕金森定律说数据会自己拓展来填满可用空间,但数据 ...

  7. SDN 第一次作业

    你会选择作 网络编程 方向的程序员吗?为什么? 答: 可能会选择吧.看了那篇文章感觉网络编程的程序员和其他的程序员都并不简单,网络编程的程序员可能更要对网络的知识更加了解.我现在也有机会能接触网络方向 ...

  8. Hadoop HA 高可用集群的搭建

    hadoop部署服务器 系统 主机名 IP centos6.9 hadoop01 192.168.72.21 centos6.9 hadoop02 192.168.72.22 centos6.9 ha ...

  9. 解决win7远程桌面连接时发生身份验证错误的方法

    远程桌面连接,是我们比较常用的一个功能了,但有时突然不能用了,以下是我遇到该问题,并解决该问题的方法.连接时报的是“发生身份验证错误,要求的函数不受支持”,解决之后细想一下,该问题好像是在我在电脑上安 ...

  10. Python 3 实现定义跨模块的全局变量和使用

    尽管某些书籍上总是说避免使用全局变量,但是在实际的需求不断变化中,往往定义一个全局变量是最可靠的方法,但是又必须要避免变量名覆盖. Python 中 global 关键字可以定义一个变量为全局变量,但 ...