什么??你问我为什么不在一篇文章写完所有方法??
Hmm…其实我是想的,但是博皮的加载速度再带上文章超长图片超多的话…
可能这辈子都打不开了吧…

上一篇:Floyed and dijkstra

福特算法(Bellman-Ford)

适用范围及时间复杂度

单源最短路径算法,可处理负边权,但,无法处理负回路的情况。时间复杂度O(NE)

N:顶点数,E:边数

核心思想

松弛计算。什么是松弛计算?你戳…

……

aaarticlea/jpeg;base64,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" alt="" />

好吧我说…

松弛计算之前,点B的值是8,但点A的值加上边上的权重2,得到点B的值是5,5<8,更新B为5。这个过程的意义是:找到了一条通向B更短的路线,且该路线先经过A,然后通过权重为2的边,到达点B。

当然,也会存在另一种情况:

在进行松弛计算之前,点B的值是6,点A加上点边上的权值4得到7>6,表示没有找到通向B点更短的路线,故B不需要更新。
这也就诠释了为什么算法不可以处理负权回路的情况。

使用松弛之后,发现程序陷入死循环。

代码实现

不难发现,在使用算法前,我们要去检验负权回路。我们需要不断地迭代以求解。

初始化

首先我们需要一个边集数组,暂定u表示起点,v表示终点,w表示权。而这个数组的长度为边的数量。

顶点数*(顶点数-1)/2。

什么?你不知道什么是边集数组?

 边集数组
边集数组是利用一维数组存储图中所有边的一种图的表示方法。
该数组中所存储的元素个数要大于等于图中所有的边数。
每个元素用来存储图一条边起点,终点和权值。
struct edge{int s,e;double w;}edges[maxn*(maxn-)/];
特别注意的是:如果是无向图,则边的数量=顶点数量*(顶点数量-)/,加边函数为:
void addEdges(int u,int v,double w){
edges[++idx].s=u;edges[idx].e=v;edges[idx].w=w;
edges[++idx].e=u;edges[idx].s=v;edges[idx].w=w;
}
而在枚举边的时候,需要枚举idx条边。
定义边集数组时,特别要注意取值范围
边集数组是针对边的,如果题目给定了边的数量为n
,那么在无向邻接矩阵中,边集数组要定义为2*n+,
必须考虑来回。如果题目只给定了顶点数p,没有给定边数,
则边集数组的取值为:p*(p-)/

因为是无向图,算法第一层循环枚举点,第二层枚举边,所以加边函数的定义应是无向图的方法。

算法核心

void bellman(){
while(--n){
bool b=false;
for(int j=;j<=idx;j++){
if(dis[edges[j].e]>dis[edges[j].s]+edges[j].w){
dis[edges[j].e]=dis[edges[j].s]+edges[j].w;
b=true;
}
}
if(!b){
break;
}
}
}

----------7.22 Update

学个A*不知道扒出来了我多少学错了的东西…这篇里面提到了最基本的福特算法,但是有一个队列优化没有补充。我一直误以为SPFA是福特算法的别称,在这里做出纠正顺便优化一下之前乱七八糟的写法。

SPFA(队列优化的Bellman-Ford)

仅仅在大陆流行叫这个优化SPFA。优化过后,在随机数据的表现情况为O(KE),K是一个较小的常数。在特殊构造中,有可能被退化成O(NE)。

优化思想是:

1.建立一个队列,最初队列中只有一个起点1

2.取出队首节点x,扫描他的所有出边(x,y,z)。如果有Dis[y]>Dis[x]+z,则用后者更新前者。同时,若y不在队列中,将y入队

3.重复以上步骤,直至队列为空。

这个队列避免了福特算法中对不需要进行扩展的节点的冗余扫描。

void spfa()
{
memset(Distance,0x3f,sizeof(Distance));
memset(Vist,,sizeof(Vist));
Distance[]=;
Vist[]=;
q.push();
while(q.size())
{
int x=q.front();
q.pop();
Vist[x]=;
for(int i=head[x]; i; i=Edges[i].Next)
{
int y=Edges[i].End,z=Edges[i].Val;
if(Distance[y]>Distance[x]+z)
{
Distance[y]=Distance[x]+z;
if(!Vist[y])
{
q.push(y),Vist[y]=;
}
}
}
}
}

最短路径算法(II)的更多相关文章

  1. Johnson 全源最短路径算法

    解决单源最短路径问题(Single Source Shortest Paths Problem)的算法包括: Dijkstra 单源最短路径算法:时间复杂度为 O(E + VlogV),要求权值非负: ...

  2. Floyd-Warshall 全源最短路径算法

    Floyd-Warshall 算法采用动态规划方案来解决在一个有向图 G = (V, E) 上每对顶点间的最短路径问题,即全源最短路径问题(All-Pairs Shortest Paths Probl ...

  3. Dijkstra 单源最短路径算法

    Dijkstra 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法,由计算机科学家 Edsger Dijkstra 于 1956 年 ...

  4. Bellman-Ford 单源最短路径算法

    Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法.该算法由 Richard Bellman 和 Leste ...

  5. 几大最短路径算法比较(Floyd & Dijkstra & Bellman-Ford & SPFA)

    几个最短路径算法的比较:Floyd 求多源.无负权边(此处错误?应该可以有负权边)的最短路.用矩阵记录图.时效性较差,时间复杂度O(V^3).       Floyd-Warshall算法(Floyd ...

  6. 带权图的最短路径算法(Dijkstra)实现

    一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...

  7. 无向图的最短路径算法JAVA实现

    一,问题描述 给出一个无向图,指定无向图中某个顶点作为源点.求出图中所有顶点到源点的最短路径. 无向图的最短路径其实是源点到该顶点的最少边的数目. 本文假设图的信息保存在文件中,通过读取文件来构造图. ...

  8. 最短路径算法之Dijkstra算法(java实现)

    前言 Dijkstra算法是最短路径算法中为人熟知的一种,是单起点全路径算法.该算法被称为是“贪心算法”的成功典范.本文接下来将尝试以最通俗的语言来介绍这个伟大的算法,并赋予java实现代码. 一.知 ...

  9. Floyd最短路径算法

    看完这篇文章写的小程序,Floyd最短路径算法,求从一个点到另一个点的最短距离,中间可以经过其他任意个点.三个for循环,从i到j依次经过k的最短距离,最外层for循环是经过点K,内部两个循环是从i( ...

随机推荐

  1. 使用OpenVPN连通管理多个阿里云VPC网络

    这篇文章比较长,将从需求.思路.原理.架构.实施步骤.细节分析.高可用等几个方面来讲述OpenVPN的使用,如果看到很熟悉的内容或者不感兴趣的部分,请您跳过. 需求 公司网络环境更换,导致原来连接阿里 ...

  2. oracle导出sequences

    将某个用户的全部sequence查询出来,并拼成创建语句: select 'create sequence '||sequence_name|| ' minvalue '||min_value|| ' ...

  3. 微信小程序 | 未来O2O电商的“阴谋”

    发展历史 2016年1月11日,微信之父张小龙时隔多年的公开亮相,提出了公众号服务的短板,而透露微信内部正在研发的新形态工具,称之"微信小程序". 2016年9月21日,微信小程序 ...

  4. C++ ACM基础

    一.C++结构体 #include <iostream> using namespace std; struct Point{ int x; int y; Point(int x=0,in ...

  5. #leetcode刷题之路8-字符串转换整数 (atoi)

    请你来实现一个 atoi 函数,使其能将字符串转换成整数.首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止.当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面 ...

  6. MySQL数据库安装配置步骤详解

    MYSQL的安装 1.打开下载的mysql安装文件mysql-5.5.27-win32.zip,双击解压缩,运行“setup.exe”. 2.选择安装类型,有“Typical(默认)”.“Comple ...

  7. Hbase过滤器

    Hbase过滤器简介 HBase的基本API,包括增.删.改.查等,增.删都是相对简单的操作,与传统的RDBMS相比,这里的查询操作略显苍白,只能根据特性的行键进行查询(Get)或者根据行键的范围来查 ...

  8. Linux GPIO键盘驱动开发记录_OMAPL138

    Linux GPIO键盘驱动开发记录_OMAPL138 Linux基本配置完毕了,这几天开始着手Linux驱动的开发,从一个最简单的键盘驱动开始,逐步的了解开发驱动的过程有哪些.看了一下Linux3. ...

  9. GeekOS: 一、构建基于Ubuntu9.04的实验环境

    参考:http://www.cnblogs.com/wuchang/archive/2009/05/05/1450311.html 补充:在最后步骤中,执行bochs即可弹出运行窗口

  10. 修改注册表删除Windows资源管理器 “通过QQ发送” 右键菜单项

    运行regedit 展开至:HKEY_CLASSES_ROOT\AllFilesystemObjects\shellex\ContextMenuHandlers 删除QQShellExt项