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算法的一种优化,但是在形 ...
随机推荐
- Django项目:CRM(客户关系管理系统)--58--48PerfectCRM实现CRM客户报名流程学生合同
# sales_urls.py # ————————47PerfectCRM实现CRM客户报名流程———————— from django.conf.urls import url from bpm. ...
- vue-cli 手机上浏览自己的项目
首先我们需要更改config文件 拿我这个项目举例子,config文件下的index.js内的dev下的host需要更改为自己的电脑IP 其次,重点来了,我们需要更改路径,细节的为什么我还解释不来,简 ...
- vim中利用swp文件进行恢复
经常电脑因为没电或者强行关闭vim,会导致原文件没有保存, 这种情况下vim会自动保存一个.swp文件,需要恢复时, 使用vim -r filename 期中-r意思为recovery 恢复之后最好删 ...
- jeecms 前台拦截器的研究与改造
jeecms 前台拦截器的研究与改造 2013年12月24日 15:23:35 xinfei0803 阅读数 3511 jeecms出发点是面向大众的,具有前台开发性,也就是说,即时是未登录(游客 ...
- Http post请求案例
public RmiRespBase sendHttpRes(String jsonParamStr, String url, String apiName,String systemId,Strin ...
- Django-rest Framework(六)
不懂使用机制的直接看源码就好了,也不是很难,能够看得懂 视图家族 1. View:将请求方式与视图类的同名方法建立映射,完成请求响应(原生django) from django.views impor ...
- StoryBoard拆分(Storyboard References)
https://www.jianshu.com/p/78dc76204c8e iOS UI篇10- Storyboard(Storyboard Reference) https://www.aliyu ...
- 5.appium命令行环境搭建及参数使用
1.安装淘宝npm(cnpm) (1)输入以下命令 :npm install -g cnpm --registry=https://registry.npm.taobao.org (2)输入cnpm ...
- Google自带截图工具的使用
转载自:http://chromecj.com/utilities/2017-12/859.html
- 纪念——代码首次达到近50K(更新:78.8K 2019行)
#include<bits/stdc++.h> #define re register #define F(A) for(re int (A)=1;(A)<=8;++(A)) usi ...