【图论】用线段树写Dijikstra!!
速度是没有极限的。
众说周知,Dijikstra是一种最短路算法,复杂度为O(V^2+E)
朴素Dijikstra
void Dijikstra(int s){
memset(dis,inf,sizeof(dis));
dis[s]=0;
for(int i=1;i<=n;++i){
int maxs=inf,u=0;
for(int j=1;j<=n;++j)
if(!vis[j]&&dis[j]<maxs)
maxs=dis[j],u=j;
vis[u]=1;
for(int e=pre[u];e;e=nx[e]){
const int v=to[e];
if(dis[v]>dis[u]+w[e])
dis[v]=dis[u]+w[e];
}
}
}
其实对于稠密图它还是很棒了。 但我们不满足于此。
常见优化-heap优化
这里我们采用STL_priority_queue进行优化
typedef pair<int,int> p;
priority_queue<p,vector<p>,greater<p> > q;
void Dijikstra(int s){
memset(dis,inf,sizeof(dis));
dis[s]=0;
q.push(p(0,s));
while(!q.empty()){
const int u=q.top().second;
q.pop();
if(!vis[u]){
vis[u]=1;
for(int e=pre[u];e;e=nx[e]){
const int v=to[e];
if(!vis[v]&&dis[v]>dis[u]+w[e])
dis[v]=dis[u]+w[e],
q.push(p(dis[v],v));
}
}
}
}
这样的话复杂度就到了O((V+E)logV) 但是,常数大。 手写堆比较复杂,不现实。
奇怪的优化-线段树优化
这并不是自己发现的,但是网上资料少就记录一下吧。 我们回头看看朴素的Dijikstra以及priority_queue优化。 发现优化的主要思路就是减少了查询当前dis最小点的复杂度。 那么也很容易想到用线段树来维护dis的最小值吧。 这样问题就变成了 整体最小值与单点修改,很简单的线段树操作吧。
int tree[N<<2],leaf;
/*线段树存的是点的标号*/
int check(int i,int j){
return dis[i]<dis[j]?i:j;
}
void build(){
memset(dis,inf,sizeof(dis));
for(leaf=1;leaf<=n;leaf<<=1);--leaf;
for(int i=1;i<=n;++i) tree[leaf+i]=i;
}
/*修改 dis[x] 为 y*/
void change(int x,int y){
dis[x]=y,x+=leaf,x>>=1;
while(x) tree[x]=check(tree[x<<1],tree[x<<1|1]),x>>=1;
}
void Dijikstra(int s){
build();
dis[s]=0;
int u=s;
for(int i=1;i<=n;++i){
ans[u]=dis[u];
change(u,max_int); /*删除u*/
for(int e=pre[u];e;e=nx[e]){
const int v=to[e];
if(dis[v]>ans[u]+w[e])
change(v,ans[u]+w[e]);
}
u=tree[1];
}
}
这个比堆短吧。 而且非递归的线段树常数也很小呢。
测试&总结
以luogu的单源最短路模板题(稀疏图,无O2)作为测试。
- 朴素的Dijikstra 2000+ms
- Dijikstra+priority_queue 652ms
- Dijikstra+线段树 192ms 然后加11了SLF和LLL的SPFA也很快,大概300ms
所以SPFA和Dijikstra+priority_queue是很实用的,但如果想卡排名的话可以试一试线段树啊
—来自xb神犇
【图论】用线段树写Dijikstra!!的更多相关文章
- codeforces 876 D. Sorting the Coins(线段树(不用线段树写也行线段树写比较装逼))
题目链接:http://codeforces.com/contest/876/problem/D 题解:一道简单的类似模拟的题目.其实就是看右边连出来有多少连续不需要换的假设位置为pos只要找pos- ...
- 2018.11.01 NOIP训练 图论(线段树+倍增+dfs序)
传送门 一道挺妙的题. 对于询问点(u,v),如右图所示,我们可以发现存在一个点m在u->v的路径中,m子树的点到u是最近的,m子树外到v是最近的.其中dis(u,m)=(dis(u,v)-1) ...
- 用线段树写Dijkstar
如题 noip前就想用线段树优化Dijkstar 写那啥,感觉挺好玩的 写了个线段树优化的Dijkstar #include<cstdio> #include<cstring> ...
- 【BZOJ-4653】区间 线段树 + 排序 + 离散化
4653: [Noi2016]区间 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 107 Solved: 70[Submit][Status][Di ...
- Mango DS Traning #49 ---线段树3 解题手记
Training address: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=38994#overview B.Xenia and B ...
- Codeforces 446-C DZY Loves Fibonacci Numbers 同余 线段树 斐波那契数列
C. DZY Loves Fibonacci Numbers time limit per test 4 seconds memory limit per test 256 megabytes inp ...
- LightOJ 1085(树状数组+离散化+DP,线段树)
All Possible Increasing Subsequences Time Limit:3000MS Memory Limit:65536KB 64bit IO Format: ...
- Vijos P1103 校门外的树【线段树,模拟】
校门外的树 描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……, ...
- BZOJ_3685_普通van Emde Boas树_权值线段树
BZOJ_3685_普通van Emde Boas树_权值线段树 Description 设计数据结构支持: 1 x 若x不存在,插入x 2 x 若x存在,删除x 3 输出当前最小值,若不存 ...
随机推荐
- 一、Github+Pycharm基础
GitHub为版本管理工具 常用的版本管理工具:本地化版本管理系统.集中式版本管理系统SVN.分布式版本管理系统 一.安装git(自行百度) 二.文件操作与分支管理基础 1.版本控制系统分类 集中化版 ...
- Mybatis学习之自定义持久层框架(六) 自定义持久层框架:完善CRUD方法并进行测试
前言 没想到会等到半年以后才来写这篇文章,我已经不记得当初自己想要在这篇文章中写什么了,还好有一些零散的笔记留着,就对照着上一篇文章及零散的笔记,把内容给补充完吧. 完善CRUD方法 完善Defaul ...
- 『居善地』接口测试 — 5、使用Requests库发送POST请求
目录 1.请求正文是application/x-www-form-urlencoded 2.请求正文是raw (1)json格式文本(application/json) (2)xml格式文本(text ...
- [re模块、json&pickle模块]
[re模块.json&pickle模块] re模块 什么是正则? 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则 ...
- Java方法区的理解
方法区逻辑上是属于堆的一部分,但一些简单的实现可能不会选择去进行垃圾收集或者进行压缩. 但对于HotSpotJVM而言,方法区还有一个别名叫做Non-Heap,目的就是要和堆分开 所以方法区看作是一块 ...
- mac 安装jmeter
1.打开jemeter网址 http://jmeter.apache.org/download_jmeter.cgi 2.下载Binaries中的 apache-jmeter-5.0.tgz 3.解压 ...
- linux 视频输出xrandr设置命令
linux 视频输出xrandr设置命令 沈祥佑关注 0.592019.03.28 17:44:09字数 397阅读 6,886 xrandr 不带参数的xrandr 命令会列出系统支持的视频接口名称 ...
- Debian 16.04 配置双网卡绑定bond
Debian 16.04 配置双网卡绑定bond Debian 16.04 bonding多网卡配置 安装负载均衡软件 fenslave root@ubuntu:~# apt-get install ...
- Zabbix 自定义report
#!/bin/bash . /etc/profile logdir='/home/admin/zabbix/zabbix_log' mysql_host='localhost' mysql_user= ...
- Ansible流程控制
Ansible流程控制 数据库操作问题: 数据库的操作问题,python需要依耐的模块MySQL-python . 数据库的操作 # 设置root的密码在,root的密码设置之后,创建用户和创建数据库 ...