线段树优化$\rm dijkstra$

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

可以得到“更新该节点影响到的线段树上的其他节点”部分的代码:
(线段树数组$\rm st[]$)

 void pushup(int x) {
st[x] = dist[st[x << ]] < dist[st[x << | ]] ? st[x << ] : st[x << | ];
} void updata(int x, int l, int r, int q) { //更新信息
if(l != r) {
int mid = (l + r) >> ;
if(q <= mid) updata(x << , l, mid, q);
else updata(x << | , mid + , r, q);
pushup(x);
}
}

然后$\rm dijkstra$代码如下:

 //此处ans为最终数组
void dijkstra(int s) {
ans[s] = dist[s] = ;
build(, , n); //建树
while(dist[st[]] < inf) {
int v = st[]; vis[v] = ; //取出最小的
for(int i = head[v]; i != -; i = edges[i].nxt) if(!vis[edges[i].to]) { //更新相邻节点
dist[edges[i].to] = min(dist[edges[i].to], dist[v] + edges[i].val);//修改dist
updata(, , n, edges[i].to);//更新所影响的节点
}
ans[v] = dist[v]; dist[v] = inf;//记录答案,删除节点
updata(, , n, v); //更新所影响的节点
}
}

完整代码:

 #include <bits/stdc++.h>

 using namespace std;

 const int MAXN = 1e5 + , inf = 0x3f3f3f3f;

 int st[MAXN << ], head[MAXN], dist[MAXN], ans[MAXN], n, m, cnt = ;
bool vis[MAXN]; struct edge {
int to, nxt, val;
} edges[MAXN << ]; void addedge(int from, int to, int val) {
edges[cnt].to = to, edges[cnt].val = val;
edges[cnt].nxt = head[from]; head[from] = cnt++;
} void pushup(int x) {
st[x] = dist[st[x << ]] < dist[st[x << | ]] ? st[x << ] : st[x << | ];
} void build(int x, int l, int r) {
if(l < r) {
int mid = (l + r) >> ;
build(x << , l, mid);
build(x << | , mid + , r);
pushup(x);
} else st[x] = l;
} void updata(int x, int l, int r, int q) {
if(l != r) {
int mid = (l + r) >> ;
if(q <= mid) updata(x << , l, mid, q);
else updata(x << | , mid + , r, q);
pushup(x);
}
} void dijkstra(int s) {
ans[s] = dist[s] = ;
build(, , n);
while(dist[st[]] < inf) {
int v = st[]; vis[v] = ;
for(int i = head[v]; i != -; i = edges[i].nxt) if(!vis[edges[i].to]) {
dist[edges[i].to] = min(dist[edges[i].to], dist[v] + edges[i].val);
updata(, , n, edges[i].to);
}
ans[v] = dist[v]; dist[v] = inf;
updata(, , n, v);
}
} int main() {
ios::sync_with_stdio(false);
memset(dist, 0x3f, sizeof(dist));
memset(head, 0xff, sizeof(head));
memset(ans, 0x3f, sizeof(ans));
int u, v, w, s;
cin >> n >> m >> s;
for(int i = ; i < m; i++) {
cin >> u >> v >> w;
addedge(u, v, w);
}
dijkstra(s);
for(int i = ; i <= n; i++) cout << ans[i] << " ";
cout << endl;
return ;
}

【Luogu P3371&P4779】【模板】单源最短路径(线段树优化Dijkstra)的更多相关文章

  1. 【洛谷 p3371】模板-单源最短路径(图论)

    题目:给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 解法:spfa算法. 1 #include<cstdio> 2 #include<cstdlib> 3 #in ...

  2. luogu P3834 【模板】可持久化线段树 1(主席树) 查询区间 [l, r] 内的第 k 小/大值

    ————————————————版权声明:本文为CSDN博主「ModestCoder_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https:// ...

  3. 【BZOJ】BZOJ3040 最短路 线段树优化Dijkstra

    题目描述 N个点,M条边的有向图,求点1到点N的最短路(保证存在). 1<=N<=1000000,1<=M<=10000000 输入格式 第一行两个整数N.M,表示点数和边数. ...

  4. [CF787D]遗产(Legacy)-线段树-优化Dijkstra(内含数据生成器)

    Problem 遗产 题目大意 给出一个带权有向图,有三种操作: 1.u->v添加一条权值为w的边 2.区间[l,r]->v添加权值为w的边 3.v->区间[l,r]添加权值为w的边 ...

  5. [模板]单源最短路径(Dijkstra)

    如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 主要还是再打一遍最短路,这种算法我用的不多... #include<bits/stdc++.h> using namesp ...

  6. luogu P3834 【模板】可持久化线段树 1(主席树)

    题解真的是越写越懒 // luogu-judger-enable-o2 #include<cstdio> #include<algorithm> using std::sort ...

  7. luogu 3834 【模板】可持久化线段树 1(主席树)

    我这种菜鸡还是%一下棒神比较好 #include<iostream> #include<cstdio> #include<cmath> #include<cs ...

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

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

  9. Dijkstra求解单源最短路径

    Dijkstra(迪杰斯特拉)单源最短路径算法 Dijkstra思想 Dijkstra是一种求单源最短路径的算法. Dijkstra仅仅适用于非负权图,但是时间复杂度十分优秀. Dijkstra算法主 ...

随机推荐

  1. genlist -s 192.168.21.\*

    显示网段192.168.21中可用的主机.

  2. 为OSSIM添加 ossec的linux agent

    1,安装环境 [root@node32 test]# yum groupinstall "Development Tools" -y Installed: byacc.x86_64 ...

  3. 查看SAP CRM和C4C的UI technical信息

    CRM 比如我们想看Quantity这个字段到底是绑在哪个模型上,选中该字段按F2: 就能知道是绑在Context node BTADMINI的QUANTITY字段上. C4C 同理,使用debugM ...

  4. POJ 3233 Matrix Power Series (矩阵分块,递推)

    矩阵乘法是可以分块的,而且幂的和也是具有线性的. 不难得到 Si = Si-1+A*Ai-1,Ai = A*Ai-1.然后矩阵快速幂就可以了. /*************************** ...

  5. Android(java)学习笔记78:Java类初始化顺序

    1. Java类中初试化的顺序: 由此得出Java普通类初始化顺序结论: (1)静态变量 (2)静态初始化块 (3)变量 (4)初始化块 (5)构造器 由此得出Java继承类初始化顺序结论: (1)继 ...

  6. Flutter /bin/sh: /packages/flutter_tools/bin/xcode_backend.sh: No such file or directory

    自己写项目中遇到的一个问题, 可以出来是路径找不到,应该是FLUTTER_ROOT这个全局变量没有取到值的原因 1.检查xcode_backend.sh 是否真的存在 2.网上说的:Target -& ...

  7. Java基础面试操作题:读取该文件内容,并按照自然顺序排序后输出到 另一个文件中

    package com.swift; import java.io.FileInputStream; import java.io.FileNotFoundException; import java ...

  8. JavaScript深拷贝与浅拷贝的理解

    个人是这么理解深拷贝和浅拷贝的:就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力. 一起看看我举的浅拷贝栗子: let ...

  9. JS位运算和遍历

    JS位运算符 整数 有符号整数:允许使用正数和负数,第32位作为符号位,前31位才是存储位 无符号整数:只允许用正数 如果用n代表位 位数 = 2^n-1 由于位数(1.2.4.8.16...)中只有 ...

  10. Linux Shell 几个特殊符号命令 & 、&& 、 ||

    & 放在启动参数后面表示设置此进程为后台进程 默认情况下,进程是前台进程,这时就把Shell给占据了,我们无法进行其他操作,对于那些没有交互的进程,很多时候,我们希望将其在后台启动,可以在启动 ...