dijkstra之zkw线段树优化
其实特别好理解,我们只要写一个数据结构(线段树)支持一下操作:
1.插入一个数\(x\)。
2.查询当前数据结构中最小的数的插入编号。
3.删除插入编号为\(x\)的数。
第一眼看成可持久化了
其实就是一个单点修改,区间(全局)查询的线段树。
zkw线段树在普通线段树的基础上进行了优化(卡常神器)。
我们记录每一个点在线段树中叶子节点的编号。这样修改的时候就不用递归下去找了,直接一个while循环pushup上来就完事。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define In inline
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e5 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
int n, m, s;
struct Edge
{
int nxt, to, w;
}e[maxn << 1];
int head[maxn], ecnt = -1;
In void addEdge(int x, int y, int w)
{
e[++ecnt] = (Edge){head[x], y, w};
head[x] = ecnt;
}
int Min[maxn << 2], id[maxn << 2], pos[maxn << 2];
In void pushup(int now)
{
if(Min[now << 1] <= Min[now << 1 | 1]) Min[now] = Min[now << 1], id[now] = id[now << 1];
else Min[now] = Min[now << 1 | 1], id[now] = id[now << 1 | 1];
}
In void build(int L, int R, int now)
{
if(L == R)
{
Min[now] = INF; id[now] = L;
pos[L] = now;
return;
}
int mid = (L + R) >> 1;
build(L, mid, now << 1), build(mid + 1, R, now << 1 | 1);
pushup(now);
}
In void update(int now, int d)
{
Min[now] = d;
while(now >> 1) pushup(now >> 1), now >>= 1;
}
bool in[maxn];
int dis[maxn];
In void dijkstra(int s)
{
Mem(dis, 0x3f), dis[s] = 0;
update(pos[s], dis[s]);
while(Min[1] ^ INF)
{
int now = id[1]; update(pos[now], INF);
if(in[now]) continue;
in[now] = 1;
for(int i = head[now], v; ~i; i = e[i].nxt)
{
if(dis[v = e[i].to] > dis[now] + e[i].w)
{
dis[v] = dis[now] + e[i].w;
update(pos[v], dis[v]);
}
}
}
}
int main()
{
Mem(head, -1);
n = read(), m = read(), s = read();
build(1, n, 1);
for(int i = 1; i <= m; ++i)
{
int x = read(), y = read(), w = read();
addEdge(x, y, w);
}
dijkstra(1);
for(int i = 1; i <= n; ++i) write(dis[i]), space; enter;
return 0;
}
dijkstra之zkw线段树优化的更多相关文章
- 堆优化/zkw线段树优化 dijkstra
#include <bits/stdc++.h> using namespace std; const int MAXN = 100005; const int MAXM = 200005 ...
- 洛谷P2505||bzoj2750 [HAOI2012]道路 && zkw线段树
https://www.luogu.org/problemnew/show/P2505 https://www.lydsy.com/JudgeOnline/problem.php?id=2750 神奇 ...
- 【Luogu P3371&P4779】【模板】单源最短路径(线段树优化Dijkstra)
线段树优化$\rm dijkstra$ 线段树每个节点维护$[l,r]$中$dist$最小的点,删除则把该点$dist$赋值为$+\infty$,然后更新该点影响到的线段树上的其他节点即可. 可以得到 ...
- 【bzoj3073】[Pa2011]Journeys 线段树优化建图+堆优化Dijkstra
题目描述 Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N编号,但是他发现道路实在太多了,他要一条条建简直是不可能的!于是他以如下方式建造道路:(a, ...
- 线段树(单标记+离散化+扫描线+双标记)+zkw线段树+权值线段树+主席树及一些例题
“队列进出图上的方向 线段树区间修改求出总量 可持久留下的迹象 我们 俯身欣赏” ----<膜你抄> 线段树很早就会写了,但一直没有总结,所以偶尔重写又会懵逼,所以还是要总结一下. ...
- 线段树和zkw线段树
作者作为一个蒟蒻,也是最近才自学了线段树,不对的地方欢迎大佬们评论,但是不要喷谢谢 好啦,我们就开始说说线段树吧 线段树是个支持区间操作和查询的东东,平时的话还是蛮实用的 下面以最基本的区间加以及查询 ...
- 【bzoj4699】树上的最短路(树剖+线段树优化建图)
题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...
- G. 神圣的 F2 连接着我们 线段树优化建图+最短路
这个题目和之前写的一个线段树优化建图是一样的. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路 之前这个题目可以相当于一个模板,直接套用就可以了. 不 ...
- B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路
B - Legacy CodeForces - 787D 这个题目开始看过去还是很简单的,就是一个最短路,但是这个最短路的建图没有那么简单,因为直接的普通建图边太多了,肯定会超时的,所以要用线段树来优 ...
随机推荐
- Laravel 最佳实践
单一职责原则 一个类和一个方法应该只有一个责任. 例如: public function getFullNameAttribute() { if (auth()->user() &&am ...
- phpstudy的设置目录列表显示403找不到
小白视角具体步骤如下 在phpstudy的->其它选项菜单->phpstudy设置->允许目录列表 phpstudy->其他选项菜单->站点域名管理(新增并保存) 然后会 ...
- Python内存相关
Python内存相关 示例一: v1 = [1, 2, 3] v2 = [1, 2 ,3] v1 = 123 v2 = 123 v1 = "dogfa" v2 = "do ...
- cygwin gcc 编译windowsAPI 报错的一个解决方案
一开始按照linux的习惯去编译一个使用了windowsAPI的程序 结果提示: $ i686-pc-cygwin-g++ screen_catch.cscreen_catch.c: In funct ...
- Class.getResources()和classLoader.getResources()区别
Class.getResource(String path) path不以’/'开头时,默认是从此类所在的包下取资源: path 以’/'开头时,则是从ClassPath根下获取: package t ...
- Pattern Recognition and Machine Learning-02-1.0-Introduction
Introduction The problem of searching for patterns in data is a fundamental one and has a long and s ...
- HTML Ueditor图片宽度超出编辑器
问题描述 Ueditor上传图片宽度尺寸超出编辑器宽度,显示异常 解决方案 ueditor.all.js 添加img宽度限制(搜索body{margin:8px;font-family:sans-se ...
- MFC基础笔记
List Control // List Control初始化,下面代码需要放在OnInitDialog()函数里面// 设置扩展风格:正行选中 m_list.SetExtendedStyle(LVS ...
- Oracle面试题及答案整理
一下题目根据此表变换 1.表:table1(FId,Fclass,Fscore),用最高效最简单的SQL列出各班成绩最高的列表,显示班级,成绩两个字段. select stu_class, max(s ...
- C#读取某一文件夹下的所有文件夹和文件
static List<string> list = new List<string>();//定义list变量,存放获取到的路径 /// <summary> // ...