Bellman-Ford(可解决负权边)--时间复杂度优化
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(可解决负权边)--时间复杂度优化的更多相关文章
- Bellman - Ford 算法解决最短路径问题
Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力 ...
- 最短路径之Bellman-Ford——解决负权边
Bellman-Ford算法非常简单,核心代码四行,可以完美的解决带有负权边的图. for(k=1;k<=n-1;k++) //外循环循环n-1次,n为顶点个数 for(i=1;i<=m; ...
- Bellman-Ford算法——解决负权边
Dijkstra算法虽然好,但是它不能解决带有负权边(边的权值为负数)的图. 接下来学习一种无论在思想上还是在代码实现上都可以称为完美的最短路径算法:Bellman-Ford算法. Bellman-F ...
- python数据结构与算法——图的最短路径(Bellman-Ford算法)解决负权边
# Bellman-Ford核心算法 # 对于一个包含n个顶点,m条边的图, 计算源点到任意点的最短距离 # 循环n-1轮,每轮对m条边进行一次松弛操作 # 定理: # 在一个含有n个顶点的图中,任意 ...
- poj3259 bellman——ford Wormholes解绝负权问题
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 35103 Accepted: 12805 Descr ...
- uva 558 - Wormholes(Bellman Ford判断负环)
题目链接:558 - Wormholes 题目大意:给出n和m,表示有n个点,然后给出m条边,然后判断给出的有向图中是否存在负环. 解题思路:利用Bellman Ford算法,若进行第n次松弛时,还能 ...
- poj 3259 bellman最短路推断有无负权回路
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 36717 Accepted: 13438 Descr ...
- Bellman—Ford算法思想
---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G ...
- Spfa 求含负权边的最短路 + 判断是否存在负权回路
在Bellman-Ford算法之后,我们总算迎来了spfa算法,其实就如同堆优化Dijkstra算法之于朴素版Dijkstra算法,spfa算法仅仅是对Bellman-Ford算法的一种优化,但是在形 ...
随机推荐
- set_case_analysis
set_case_analysis给某个Pin指定固定电平,然后时序分析会根据该结果优化原先的电路. 试举例如下:
- webpack打包less与sass
less 1.安装 less-loader 与 less npm install less-loader less --save-dev 2.配置webpack.config.js module.ex ...
- 左神算法书籍《程序员代码面试指南》——2_11将单链表的每K个节点之间逆序
[题目]给定一个单链表的头节点head,实现一个调整单链表的函数,使得每K个节点之间逆序,如果最后不够K个节点一组,则不调整最后几个节点.例如:链表:1->2->3->4->5 ...
- Java 如何在线打开编辑word文档?
在一般的OA项目中经常会遇到在线处理Office文档的需求,先下载文件,编辑保存后再选择文件上传的方式太过原始,在如今早已是Office Online的时代,没有用户能接受这种蹩脚的操作方式. 虽然微 ...
- FamilyFilter(4)
3.1. 基于列族过滤数据的FamilyFilter 构造函数: FamilyFilter(CompareFilter.CompareOp familyCompareOp, ByteArrayComp ...
- tr的display属性出现td的colspan无效问题
http://www.aichengxu.com/other/9262680.htm 今天在做项目的时候发现用javascript控制 tr 的显示隐藏时,当把tr的显示由“display:none” ...
- Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---状态模式[转]
{没有应用状态模式的代码} //工程文件 program Project1; {$APPTYPE CONSOLE} uses uGumballMachine in 'uGumballMachine. ...
- 读书笔记--Head First 面向对象分析与设计 目录
1.良好应用程序的基石 2.收集需求 3.需求变更 4.分析 5.良好的设计=灵活的软件 6.解决大问题 7.架构 8.设计原则 9.迭代与测试 10.OOA&D 的生命周期 附录1 附录2
- 基于python爬虫的github-exploitdb漏洞库监控与下载
基于python爬虫的github-exploitdb漏洞库监控与下载 offensive.py(爬取项目历史更新内容) #!/usr/bin/env python # -*- coding:utf- ...
- java-面向对象-封装-this-构造函数
概要图 一 构造函数 需求:为了描述事物更准确,发现事物对应的很多对象一创建时, 就有了,一些初始化的数据.在类中该如何完成的. 通过Java中的另一个小技术完成:就是构造函数.对象本身就是构造出 ...