最短路算法整理

1.Dijkstra 算法

先讲讲朴素的Dijkstra算法的思路.朴素的Dijkstra算法先将起点入队.然后找到一个起点距离最近的点.再用这个点去更新其他所有的点.一共有多少个点就进行多少次迭代.因为每次找到一个用于更新距离的点.它的最短距离就已经确定了.

核心代码:

#include <iostream>
#include <cstring>
using namespace std;
#define INF 0x3f3f3f
const int N = 510;
int n,m,g[N][N],st[N],dist[N];
void dijkstra()
{fill(dist,dist+N,INF);dist[1] = 0;for(int i=1;i<=n;i++){int t = -1;//第一次t一定 = 起点for(int j=1;j<=n;j++)if(!st[j]&&(t==-1||dist[j]<dist[t])) t = j;//确定距离最短的点for(int j=1;j<=n;j++)dist[j] = min(dist[t]+g[t][j],dist[j]);//更新其他距离st[t] = 1;}if(dist[n]==INF) printf("-1\n");else printf("%d\n",dist[n]);
}

这种方法复杂度很高,需要优化.因为第一个j循环本质是找到当前距离最小的点,所以可以用优先队列优化.dijkstra的st数组表示的是当前点的最短距离是否被确定.

因此出现了堆优化版的dijkstra算法.

核心代码:

int dijkstra()
{memset(dist,0x3f,sizeof dist);dist[1] = 0;//dist[i]表示起点到i的距离priority_queue<pii,vector<pii>,greater<pii> > q;//存储的是距离 与谁的距离q.push({0,1});while(q.size()){auto it = q.top();q.pop();if(st[it.second]) continue;st[it.second] = 1;for(int i=h[it.second];i!=-1;i=ne[i]){int j = e[i];if(dist[it.second]+w[i]<dist[j]) { dist[j] = dist[it.second]+w[i]; q.push({dist[j],j});}}}if(dist[n]==0x3f3f3f3f) return -1;return dist[n];
}

每次st数组被标为1,说明当前点的最短距离已经确定了.

Dijkstra的优点是某些卡SPFA的题它不会被卡.所以单源最短路优先用Dijkstra.

时间复杂度O(m l o g 2 n log_2 n log2​n)

2.SPFA 算法

这个算法与Dijkstra算法十分相似.但它本质是对BF算法的一个优化.BF算法每次枚举一个点,再用所有的点去更新当前点的最短距离.SPFA算法就是对其进行了优化.它的核心思想是对于当前队头,将它所有能更新的点入队.反复此过程直到不能更新了为止.

这里的st数组表示当前点是否在队列中.

核心代码:

void spfa(int s)
{fill(dist,dist+N,0x3f3f3f3f);dist[s] = 0;queue<int> q;q.push(s);st[s] = 1;while(q.size()){int t = q.front();q.pop();st[t] = 0;for(int i=h[t];i!=-1;i=ne[i]){int j = e[i];if(dist[j]>dist[t]+w[i]){dist[j] = dist[t]+w[i];//写在外面,应为相同点对应边不同也可以更新距离if(!st[j]) q.push(j),st[j] = 1;}}}if(dist[n]==0x3f3f3f3f) printf("impossible\n");else printf("%d\n",dist[n]);
}

因为st数组的值在反复变化,并且队列也不是按距离进行排序.所以每个点都有多次入队的机会.如果用数组实现队列需要用循环队列.

时间复杂度O(m) m指边的数量.

因为队列可以多次入队同一点.所以SPFA算法可以用来处理负边权和判负环.

cnt数组表示入队次数,也就是有多少边能到此点.如果cnt[t]>n 说明出现了环.

核心代码:

bool spfa(int n)
{queue<int> q;for(int i=1;i<=n;i++) { q.push(i); st[i] = 1;}while(q.size())//如果存在负环,到路径上最后一个点->初始点d<=0,所以可以继续更新.{//初始点进入时,其他点的st都被置0int t = q.front();q.pop();st[t] = 0;for(int i=h[t];i!=-1;i=ne[i]){int j = e[i];if(dist[j]>dist[t]+w[i]){cnt[j] = cnt[t]+1;//放外面的原因应该是如果队列里还有更短的路径可到j,更方便更新if(cnt[j]>n) return true;dist[j] = dist[t]+w[i];if(!st[j]) q.push(j),st[j] = 1;}}}return false;
}

最短路算法整理 七七八八的总结相关推荐

  1. 最短路算法整理 1557 热浪

    1557 热浪  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond  题目描述 Description 德克萨斯纯朴的民眾们这个夏天正在遭受巨大的热浪!!!他 ...

  2. spfa算法_10行实现最短路算法——Dijkstra

    今天是算法数据结构专题的第34篇文章,我们来继续聊聊最短路算法. 在上一篇文章当中我们讲解了bellman-ford算法和spfa算法,其中spfa算法是我个人比较常用的算法,比赛当中几乎没有用过其他 ...

  3. (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法模板的整理与介绍

    这一篇博客以一些OJ上的题目为载体.整理一下最短路径算法.会陆续的更新... 一.多源最短路算法--floyd算法 floyd算法主要用于求随意两点间的最短路径.也成最短最短路径问题. 核心代码: / ...

  4. 综合算法05—考虑换乘的K短路算法

    一.问题描述 在路网中,已知站点.线路和线路-站点数据,有条件: 1.考虑到换乘时要花费一定的时间,因此对换乘路径费用要加上换乘时间. 2.当路网复杂时,为了避免多余计算,定义有效路径,使得路径在有效 ...

  5. 最短路算法总结(入门版)

    最近花了大约一个月左右的时间集中刷了一些图论的题目.虽然收获了许多但是还是付出了很多作业没有做的代价0.0.在这里先把自己所做的关于最短路的基础算法来做一个总结,至少把学到的东西记录下来. 先说明一下 ...

  6. dijkstra算法matlab程序_编程习题课 | 用最短路算法为你的小地图导航

    简介:路网拓扑的正确导入方式,运筹学算法的完整实战案例,最详细的代码讲解与分享. 引言:在研究路径选择和流量分配等交通问题时,常常会用到最短路算法.用最短路算法解决交通问题存在两个难点:一.算法的选择 ...

  7. (最短路径算法整理)dijkstra、floyd、bellman-ford、spfa算法

    一.floyd 1.介绍 floyd算法只有五行代码,代码简单,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3),可以求多源最短路问题. 2.思想: Floyd算法的基本思想如下:从任意 ...

  8. 坐在马桶上看算法:Dijkstra最短路算法

                                                             [坐在马桶上看算法]算法7:Dijkstra最短路算法 上周我们介绍了神奇的只有五行的 ...

  9. 坐在马桶上看算法:只有五行的Floyd最短路算法

    坐在马桶上看算法:只有五行的Floyd最短路算法 此算法由Robert W. Floyd(罗伯特·弗洛伊德)于1962年发表在"Communications of the ACM" ...

最新文章

  1. CSS:给 input 中 type=text 设置CSS样式
  2. redis.conf 配置项说明
  3. 程序设计原则——优化程序
  4. UNIX再学习 -- TCP/UDP 客户机/服务器
  5. 八十四、SpringBoot微服务Dubbo和Zookeeper分布式
  6. iOS中的唯一标示符
  7. android布局中使用include及需注意点
  8. codeforces 283C
  9. 集成mysql+tomcat+apache+Eclipse的绿色版开发环境
  10. Python办公自动化--Word、Excel、PDF
  11. 【知了堂学习心得】浅谈c3p0连接池和dbutils工具类的使用
  12. Halcon 注册说明
  13. 白话区块链 之 14 - ​区块链的技术意义
  14. 哈工大车万翔教授:ACL 2010-2020研究趋势总结
  15. 串级调节系统参数整定方法(串级调节器参数整定)
  16. 80后,我们难忘的电视剧
  17. 怎么修改win8计算机用户名和密码忘了怎么办,win8怎么修改用户名 Win8修改用户名与目录名的办法...
  18. Hbase数据库完全分布式搭建以及java中操作Hbase
  19. 【杂耍】记录一次红米Note的救砖经历
  20. Android MediaPalyer实现视频播放

热门文章

  1. 【算法】图像处理在医学领域的应用
  2. c++矩阵转置_线性代数中的向量矩阵
  3. 2018几大主流的UI/JS框架——前端框架
  4. 官方也无力回天?“SharedPreferences 存在什么问题?”
  5. [APIO2018] New Home 新家
  6. kubectl查看node状态_K8S常用命令
  7. 估值冰火两重天 互联网金融巨头“天价”冲刺上市
  8. 编写判断一个正整数是否为素数的函数
  9. SecureCRT8.0X 高亮配色方案
  10. 穿越NAT的SDWAN技术实现(下)