速度是没有极限的。

众说周知,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!!的更多相关文章

  1. codeforces 876 D. Sorting the Coins(线段树(不用线段树写也行线段树写比较装逼))

    题目链接:http://codeforces.com/contest/876/problem/D 题解:一道简单的类似模拟的题目.其实就是看右边连出来有多少连续不需要换的假设位置为pos只要找pos- ...

  2. 2018.11.01 NOIP训练 图论(线段树+倍增+dfs序)

    传送门 一道挺妙的题. 对于询问点(u,v),如右图所示,我们可以发现存在一个点m在u->v的路径中,m子树的点到u是最近的,m子树外到v是最近的.其中dis(u,m)=(dis(u,v)-1) ...

  3. 用线段树写Dijkstar

    如题 noip前就想用线段树优化Dijkstar 写那啥,感觉挺好玩的 写了个线段树优化的Dijkstar #include<cstdio> #include<cstring> ...

  4. 【BZOJ-4653】区间 线段树 + 排序 + 离散化

    4653: [Noi2016]区间 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 107  Solved: 70[Submit][Status][Di ...

  5. Mango DS Traning #49 ---线段树3 解题手记

    Training address: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=38994#overview B.Xenia and B ...

  6. 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 ...

  7. LightOJ 1085(树状数组+离散化+DP,线段树)

    All Possible Increasing Subsequences Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format: ...

  8. Vijos P1103 校门外的树【线段树,模拟】

    校门外的树 描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,……, ...

  9. BZOJ_3685_普通van Emde Boas树_权值线段树

    BZOJ_3685_普通van Emde Boas树_权值线段树 Description 设计数据结构支持: 1 x  若x不存在,插入x 2 x  若x存在,删除x 3    输出当前最小值,若不存 ...

随机推荐

  1. 利用cm压缩包手动安装cm和cdh

    安装准备: 1.操作系统为centos6.9 CentOS-6.9-x86_64-bin-DVD1to2 2.安装Oracle JDK (1.8u121) 下载jdk-8u121-linux-x64. ...

  2. 阿里面试官用HashMap把我问倒了

    本人是一名大三学生,最近在找暑期实习,其中也面试过两次阿里,一次菜鸟网络部门.一次网商银行部门,当然我都失败了,同时也让我印象很深刻,因此记录了其中一些面试心得,我觉得这个问题很值得分享,因此分享给大 ...

  3. File & Directory

    新开一节IO(Input/Output)的用法. 这节主要讲一下操作文件和文件目录的两个静态类:File 和 Directory. 在进入正题之前,先理解一下相对路径和绝对路径这两个概念: 绝对路径, ...

  4. SpringBoot中获取上下文

    在实际开发中,有时候会根据某个bean的名称或class到Spring容器中获取对应的Bean.这里只做个简单的记录,方便后续自查. @Component public class SpringCon ...

  5. 15.Git

    1.Git介绍 1.1版本控制(理解) 无论是代码编写,还是文档编写,我们都会遇到对文档内容反复修改的情况 1.2开发中存在的问题(理解) 程序员小明负责的模块就要完成了,就在即将提交发布之前的一瞬间 ...

  6. [Java] HOW2J(Java中级)

    异常 定义:导致程序正常流程被中断的事件 异常处理常见手段 try catch:将可能抛出异常的代码放在try的块中,一旦出现异常就跳转到catch的块中处理 throws/throw:不在本模块处理 ...

  7. [前端] AJAX

    背景 Asynchronous JavaScript And XML:异步js和XML,可实现异步刷新 用途 验证提交的用户名是否已存在 不使用AJAX,需要提交数据后,刷新页面来验证 使用AJAX, ...

  8. 【BIGDATA】Grafana告警之webhook的坑

    近日搭建一套基于ELK&Grafana的监控告警平台,目的是将生产端某性能日志导入ES中,通过Grafana进行可视化监测,同时设置告警. 告警内容推送到自建的webhook服务后,转发到指定 ...

  9. 10.27-Redis-mz 深入浅出Redis

    深入浅出Redis 1.Redis的发展史     Redis[Remote Directory Server]:远程服务器字典 2.下载安装Redis 1>Linux下安装Reids     ...

  10. Java 事务的隔离级别

    引言 之前关于事务的文章已介绍了事务的概念以及事务的四个属性(ACID),相信你对事务应该有所认识和了解. 本篇文章是关于事务的隔离性,介绍数据库提供的多种隔离级别. 数据库访问的并发性问题 所谓事务 ...