其实特别好理解,我们只要写一个数据结构(线段树)支持一下操作:

1.插入一个数\(x\)。

2.查询当前数据结构中最小的数的插入编号。

3.删除插入编号为\(x\)的数。




第一眼看成可持久化了

其实就是一个单点修改,区间(全局)查询的线段树。

zkw线段树在普通线段树的基础上进行了优化(卡常神器)。

我们记录每一个点在线段树中叶子节点的编号。这样修改的时候就不用递归下去找了,直接一个while循环pushup上来就完事。

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<cmath>
  4. #include<algorithm>
  5. #include<cstring>
  6. #include<cstdlib>
  7. #include<cctype>
  8. #include<vector>
  9. #include<stack>
  10. #include<queue>
  11. using namespace std;
  12. #define enter puts("")
  13. #define space putchar(' ')
  14. #define Mem(a, x) memset(a, x, sizeof(a))
  15. #define In inline
  16. typedef long long ll;
  17. typedef double db;
  18. const int INF = 0x3f3f3f3f;
  19. const db eps = 1e-8;
  20. const int maxn = 1e5 + 5;
  21. inline ll read()
  22. {
  23. ll ans = 0;
  24. char ch = getchar(), last = ' ';
  25. while(!isdigit(ch)) last = ch, ch = getchar();
  26. while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
  27. if(last == '-') ans = -ans;
  28. return ans;
  29. }
  30. inline void write(ll x)
  31. {
  32. if(x < 0) x = -x, putchar('-');
  33. if(x >= 10) write(x / 10);
  34. putchar(x % 10 + '0');
  35. }
  36. int n, m, s;
  37. struct Edge
  38. {
  39. int nxt, to, w;
  40. }e[maxn << 1];
  41. int head[maxn], ecnt = -1;
  42. In void addEdge(int x, int y, int w)
  43. {
  44. e[++ecnt] = (Edge){head[x], y, w};
  45. head[x] = ecnt;
  46. }
  47. int Min[maxn << 2], id[maxn << 2], pos[maxn << 2];
  48. In void pushup(int now)
  49. {
  50. if(Min[now << 1] <= Min[now << 1 | 1]) Min[now] = Min[now << 1], id[now] = id[now << 1];
  51. else Min[now] = Min[now << 1 | 1], id[now] = id[now << 1 | 1];
  52. }
  53. In void build(int L, int R, int now)
  54. {
  55. if(L == R)
  56. {
  57. Min[now] = INF; id[now] = L;
  58. pos[L] = now;
  59. return;
  60. }
  61. int mid = (L + R) >> 1;
  62. build(L, mid, now << 1), build(mid + 1, R, now << 1 | 1);
  63. pushup(now);
  64. }
  65. In void update(int now, int d)
  66. {
  67. Min[now] = d;
  68. while(now >> 1) pushup(now >> 1), now >>= 1;
  69. }
  70. bool in[maxn];
  71. int dis[maxn];
  72. In void dijkstra(int s)
  73. {
  74. Mem(dis, 0x3f), dis[s] = 0;
  75. update(pos[s], dis[s]);
  76. while(Min[1] ^ INF)
  77. {
  78. int now = id[1]; update(pos[now], INF);
  79. if(in[now]) continue;
  80. in[now] = 1;
  81. for(int i = head[now], v; ~i; i = e[i].nxt)
  82. {
  83. if(dis[v = e[i].to] > dis[now] + e[i].w)
  84. {
  85. dis[v] = dis[now] + e[i].w;
  86. update(pos[v], dis[v]);
  87. }
  88. }
  89. }
  90. }
  91. int main()
  92. {
  93. Mem(head, -1);
  94. n = read(), m = read(), s = read();
  95. build(1, n, 1);
  96. for(int i = 1; i <= m; ++i)
  97. {
  98. int x = read(), y = read(), w = read();
  99. addEdge(x, y, w);
  100. }
  101. dijkstra(1);
  102. for(int i = 1; i <= n; ++i) write(dis[i]), space; enter;
  103. return 0;
  104. }

dijkstra之zkw线段树优化的更多相关文章

  1. 堆优化/zkw线段树优化 dijkstra

    #include <bits/stdc++.h> using namespace std; const int MAXN = 100005; const int MAXM = 200005 ...

  2. 洛谷P2505||bzoj2750 [HAOI2012]道路 && zkw线段树

    https://www.luogu.org/problemnew/show/P2505 https://www.lydsy.com/JudgeOnline/problem.php?id=2750 神奇 ...

  3. 【Luogu P3371&P4779】【模板】单源最短路径(线段树优化Dijkstra)

    线段树优化$\rm dijkstra$ 线段树每个节点维护$[l,r]$中$dist$最小的点,删除则把该点$dist$赋值为$+\infty$,然后更新该点影响到的线段树上的其他节点即可. 可以得到 ...

  4. 【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra

    题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a, ...

  5. 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题

    “队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄>     线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...

  6. 线段树和zkw线段树

    作者作为一个蒟蒻,也是最近才自学了线段树,不对的地方欢迎大佬们评论,但是不要喷谢谢 好啦,我们就开始说说线段树吧 线段树是个支持区间操作和查询的东东,平时的话还是蛮实用的 下面以最基本的区间加以及查询 ...

  7. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

  8. G. 神圣的 F2 连接着我们 线段树优化建图+最短路

    这个题目和之前写的一个线段树优化建图是一样的. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路 之前这个题目可以相当于一个模板,直接套用就可以了. 不 ...

  9. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路

    B - Legacy CodeForces - 787D 这个题目开始看过去还是很简单的,就是一个最短路,但是这个最短路的建图没有那么简单,因为直接的普通建图边太多了,肯定会超时的,所以要用线段树来优 ...

随机推荐

  1. Laravel入门

    一.下载Laravel ①github上下载 ②通过composer下载,推荐 第一步,选择你要在哪个目录下载Laravel,打开cmd 第二步,打开https://docs.golaravel.co ...

  2. PHP max_input_var设为了1000导致post数组太多时无法接受后面的参数值

    PHP max_input_var设为了1000导致post数组太多时无法接受后面的参数值 下午突然接到格力电话说无法批量设置门店任务,但是在测试环境下无法重现,测试环境下好好的. 然后登陆到生产环境 ...

  3. Idea中maven的设置

    File->setting    输入MAVEN     看到右侧设置情况     Maven home directory 熟路本地moven 仓库目录:D:/springboot/apach ...

  4. Python 第一节随堂练习

    作业: 1 从键盘输入一个整数,判断该数字能否被2和3同时整除,能否被2整除,能否被3整除,不能被2和3整除,输出相应信息 1 my_num = int(input('请输入一个整数')) 2 if ...

  5. hdu 1671 复习字典树

    #include<cstdio> #include<iostream> #include<string> #include<cstdlib> #defi ...

  6. hdu 2821 学习一点dfs的小技巧吧。。 还是自己太弱了

    #include<iostream> #include<cstdio> #include<cstring> using namespace std; int r,c ...

  7. Idea加载项目扫描完毕后自动退出

    问题描述:Idea平时好好的,突然就打开后扫描完毕后自动退出.网上说修改idea.exe.vmoptions文件的Xmx,还是不行. 后来根据http://www.pianshen.com/artic ...

  8. TCP协议探究(四):定时器

    1 概述 重传定时器:使用于当希望收到另一端的确认. 坚持(persist)定时器:使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口 保活(keepalive)定时器:用于检测一个空闲连接的另一 ...

  9. TCP协议探究(二):超时与重试

    1 概述 TCP提供可靠的运输层. 可靠性保证之一:确认从另一端收到的数据. 但数据和确认都有可能会丢失.TCP通过在发送时设置一个定时器来解决这种问题. 如果当定时器溢出时还没有收到确认,它就重传该 ...

  10. Linux与Windows的设备驱动模型对比

    Linux与Windows的设备驱动模型对比 名词缩写: API 应用程序接口(Application Program Interface ) ABI 应用系统二进制接口(Application Bi ...