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算法的一种优化,但是在形 ...
随机推荐
- 【codeforces 507E】Breaking Good
[题目链接]:https://vjudge.net/contest/164884#problem/D [题意] 给你一张图; 图中有些路是完好的;但有些路还没修好; 先不管路有没有修好; 问你从起点到 ...
- C++与Matlab混合编程之:矩阵数据结构
项目需要将matlab代码写成C++,准备用opencv.opencv中矩阵的存储与matlab有所不同,应注意以下问题: 1.matlab中矩阵是按照列优先存储的.对于n0*n1*...*nn维的矩 ...
- Django项目:CRM(客户关系管理系统)--59--49PerfectCRM实现CRM客户报名流程学生合同表单验证
# sales_views.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.db import IntegrityError #主动捕 ...
- 二叉查找树、平衡二叉树(AVL)、B+树、联合索引
1. [定义] 二叉排序树(二拆查找树)中,左子树都比节点小,右子树都比节点大,递归定义. [性能] 二叉排序树的性能取决于二叉树的层数 最好的情况是 O(logn),存在于完全二叉排序树情况下,其访 ...
- webServices学习一(了解基础和作用。)
一.第一部分 1. 带着几个问题学习: l 什么是WebService? l 它能做什么? l 为什么要学习WebService? l 学习WebService ...
- python 中的split()函数和os.path.split()函数
Python中有split()和os.path.split()两个函数: split():拆分字符串.通过指定分隔符对字符串进行切片,并返回分割后的字符串列表. os.path.split():将文件 ...
- pc端拖拽
var move=document.getElementsByClassName("page1_2")[0]; var startX=0; var startY=0; var x= ...
- Css 进阶学习
以下样式,表示css对第一个li标签无效,第一个以后的样式有效. .nav-pills>li+li { margin-left: 2px } <ul class="nav-pil ...
- 在C#应用中使用Common Logging日志接口
我在C#应用中一般使用log4net来记录日志,但如果项目中有个多个工程,那么没有工程都需要引用log4neg,感觉很不爽.不过今日在开spring.net的时候,看到了有个通用日志接口Common ...
- mysql_example
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysq ...