Bellman-Ford 可解决带有负权边的最短路问题

  解决负权边和Dijkstra相比是一个优点,Bellman-Ford的核心代码只有4行::

u[],v[],w[] 分别存一条边的顶点、权值,dis[]存从 1 源点到各个顶点的距离

for(i=;i<=n-;i++)
for(j=;j<=m;j++)
if(dis[v[j]] > dis[u[j]]+w[j])
dis[v[j]] = dis[u[j]]+w[j];

  愿过程:

      循环n-1次,把每个顶点每条边都松弛;

优化方法:

      ①,最坏的情况就是循环了n-1次才求出到每个顶点的最短路径,若果在n-1次之前就已经全部松弛完成,那么后面的循环就是多余

        优化:

for(k=;k<=n-;k++)//共有 n 个顶点,循环n-1次即可
{
flag = ;
for(i=;i<=m;i++)//对当前所有的边进行松弛
{
if(dis[v[i]] > dis[u[i]]+w[i])
{
dis[v[i]] = dis[u[i]]+w[i];
flag = ;
}
}
if(flag == ) break;//松弛也完成,结束
}

      ②,原过程:每次循环松弛过后,都有已经确定了的源点到某点最短的路径,此后这些顶点的最短路的值就会一直保持不变,不再受后续松弛操作的影响,但是每次还要判断是否需要松弛,这里浪费了时间。

     优化:确定一条边后总边数减一,把不能进行本次松弛的边再次后头存到原数组,松弛成功的边舍弃,再次松弛时只对未松弛的边进行操作,m的值会随着松弛预越来越小,直到全部完成。

for(k=;k<=n-;k++)//共有 n 个顶点,循环n-1次即可
{
m = M;//重新赋值后的 m 是数组中存储边的条数
s = ;flag = ;
for(i=;i<=m;i++)//对当前所有的边进行松弛
{
if(dis[v[i]] > dis[u[i]]+w[i])
{
dis[v[i]] = dis[u[i]]+w[i];
M--; //松弛成功,边数减一
flag = ;
}
else//把本次不能进行松弛的边重新存储到当前的数组
{
u[s] = u[i];
v[s] = v[i];
w[s] = w[i];
s++;
}
}
if(flag == ) break;//松弛也完成,结束
}

附完整代码:

#include <stdio.h>
int main()
{
int dis[],i,k,m,n,s=,u[],v[],w[],M,flag;
int inf = ;
scanf("%d%d",&n,&m);
M = m;
for(i=;i<=m;i++)
{
scanf("%d%d%d",&u[i],&v[i],&w[i]);//输入各边及权值
}
for(i=;i<=n;i++)
{
dis[i] = inf;//初始化为正无穷
}
dis[] = ;//以 1 为源点 for(k=;k<=n-;k++)//共有 n 个顶点,循环n-1次即可
{
m = M;//重新赋值后的 m 是数组中存储边的条数
s = ;flag = ;
for(i=;i<=m;i++)//对当前所有的边进行松弛
{
if(dis[v[i]] > dis[u[i]]+w[i])
{
dis[v[i]] = dis[u[i]]+w[i];
M--; //松弛成功,边数减一
flag = ;
}
else//把本次不能进行松弛的边重新存储到当前的数组
{
u[s] = u[i];
v[s] = v[i];
w[s] = w[i];
s++;
}
}
if(flag == ) break;//松弛也完成,结束
} for(i=;i<=n;i++)
{
printf("%d ",dis[i]);
}
return ;
}

测试数据1:

5 5
2 3 2
1 2 -3
1 5 5
4 5 2
3 4 3

运行结果:

0 -3 -1 2 4

测试数据2:

5 7
1 2 2
1 5 10
2 3 3
2 5 7
3 4 4
4 5 5
5 3 6

运行结果:

0 2 5 9 9

Bellman-Ford(可解决负权边)--时间复杂度优化的更多相关文章

  1. Bellman - Ford 算法解决最短路径问题

    Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力 ...

  2. 最短路径之Bellman-Ford——解决负权边

    Bellman-Ford算法非常简单,核心代码四行,可以完美的解决带有负权边的图. for(k=1;k<=n-1;k++) //外循环循环n-1次,n为顶点个数 for(i=1;i<=m; ...

  3. Bellman-Ford算法——解决负权边

    Dijkstra算法虽然好,但是它不能解决带有负权边(边的权值为负数)的图. 接下来学习一种无论在思想上还是在代码实现上都可以称为完美的最短路径算法:Bellman-Ford算法. Bellman-F ...

  4. python数据结构与算法——图的最短路径(Bellman-Ford算法)解决负权边

    # Bellman-Ford核心算法 # 对于一个包含n个顶点,m条边的图, 计算源点到任意点的最短距离 # 循环n-1轮,每轮对m条边进行一次松弛操作 # 定理: # 在一个含有n个顶点的图中,任意 ...

  5. poj3259 bellman——ford Wormholes解绝负权问题

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 35103   Accepted: 12805 Descr ...

  6. uva 558 - Wormholes(Bellman Ford判断负环)

    题目链接:558 - Wormholes 题目大意:给出n和m,表示有n个点,然后给出m条边,然后判断给出的有向图中是否存在负环. 解题思路:利用Bellman Ford算法,若进行第n次松弛时,还能 ...

  7. poj 3259 bellman最短路推断有无负权回路

    Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 36717   Accepted: 13438 Descr ...

  8. Bellman—Ford算法思想

    ---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G ...

  9. Spfa 求含负权边的最短路 + 判断是否存在负权回路

    在Bellman-Ford算法之后,我们总算迎来了spfa算法,其实就如同堆优化Dijkstra算法之于朴素版Dijkstra算法,spfa算法仅仅是对Bellman-Ford算法的一种优化,但是在形 ...

随机推荐

  1. Range的范围

    range(N,M)的范围应为: [N,M) 例如:

  2. E: 无法获得锁 /var/lib/apt/lists/lock - open (11: 资源暂时不可用) E: 无法对目录 /var/lib/apt/lists/ 加锁 问题解决方法

    使用Ubuntu16.04安装软件执行apt-get update时出现如下错误: E: 无法获得锁 /var/lib/apt/lists/lock - open (11: 资源暂时不可用) E: 无 ...

  3. Elasticsearch 5.6.4 window 安装并简单使用head

    1.现在elasticsearch安装包 https://www.elastic.co/downloads/elasticsearch 2.解压elasticsearch-5.6.4.zip 到需要安 ...

  4. c语言学习笔记 关于double

    今天做了个简单的例子,由于没有使用正确的数据类型导致出错,下面是记录 #include <stdio.h> int main(void){ int i; double sum; doubl ...

  5. 软件-MQ-MQ:IBM MQ

    ylbtech-软件-MQ-MQ:MQ(IBM MQ) MQ传递主干,在世界屡获殊荣. 它帮您搭建企业服务总线(ESB)的基础传输层.IBM WebSphere MQ为SOA提供可靠的消息传递.它为经 ...

  6. 原生JS实现简易计算器

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  7. 60行JavaScript代码俄罗斯方块

    教你看懂网上流传的60行JavaScript代码俄罗斯方块游戏   早就听说网上有人仅仅用60行JavaScript代码写出了一个俄罗斯方块游戏,最近看了看,今天在这篇文章里面我把我做的分析整理一下( ...

  8. 【DM642学习笔记四】flash烧写过程——错误记录…

    (欢迎批评指正) 一,打开.cdd配置文件时出错: 解决:在FlashBurn配置窗口中,Conversion Cmd一栏可不用管:      菜单Program—Download FBTC,load ...

  9. mapreduce join操作

    上次和朋友讨论到mapreduce,join应该发生在map端,理由太想当然到sql里面的执行过程了 wheremap端 join在map之前(笛卡尔积),但实际上网上看了,mapreduce的笛卡尔 ...

  10. 2019-10-11-VisualStudio-配置多进程调试快捷键启动项目

    title author date CreateTime categories VisualStudio 配置多进程调试快捷键启动项目 lindexi 2019-10-11 15:33:32 +080 ...