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算法的一种优化,但是在形 ...
随机推荐
- SPSS统计分析案例:无空白列重复正交试验设计方差分析
SPSS统计分析案例:无空白列重复正交试验设计方差分析 前面有讲过 SPSS正交试验设计及其方差分析 一篇文章,包含了一个典型的正交试验案例.然而在实际应用当中,主观客观条件复杂多变,在试验设计中就要 ...
- 此处有加速 apt-get github docker pull
ubuntu get-apt 加速 创建 aptupdate.sh 脚本,内容为: #!/bin/bash mv /etc/apt/sources.list /etc/apt/sources.list ...
- PAT甲级——A1054 The Dominant Color
Behind the scenes in the computer's memory, color is always talked about as a series of 24 bits of i ...
- DVWA 之high级别sql注入
Sqlmap 高级注入,抓包,然后保存数据到1.txt 1.判断注入点 sqlmap -r /root/1.txt -p id --second-order "ht ...
- 【DM8168学习笔记3】CodSourcery GCC Tool Chain安装过程记录
eagle@eagle-desktop:~$ cd/home/eagle/desktop eagle@eagle-desktop:~/desktop$ cd./vboxshared eagle@eag ...
- Junit5的依赖添加及RunWith(SpringJUnit4ClassRunner.class)注解使用
首先Junit5依赖应该配置为 <dependency> <groupId>org.junit.jupiter</groupId> <artifactId&g ...
- 11.5 临近csp·道别
差不多到写这个东西的时候了? 嗯,按今天的日期来算的话,还有不到十天就是csp.感觉对我这种家伙来说应该算是终结了? 放在之前的话肯定会写很多东西的,不过现在大约有点不知道写什么比较合适. 所以只是祝 ...
- 粗浅看 Tomcat系统架构分析
原文出处: 吴士龙 http://www.importnew.com/21112.html Tomcat的结构很复杂,但是Tomcat也非常的模块化,找到了Tomcat最核心的模块,就抓住了Tomca ...
- LA2238 Fixed Partition Memory Management
题目大意: m(m<=10)个内存区域,n(n<=50)个程序.找出一个方案来,使得平均结束时刻尽量小.题目保证有解. 同一个程序运行在不同大小的内存区域内,其运行时间不同.(注意,这里说 ...
- odoo web controller
Routing openerp.http.route(route=None, **kw) Decorator marking the decorated method as being a handl ...