中级篇——Bellmen算法求最短路径
来源:互联网 发布:黑马java 2016 编辑:程序博客网 时间:2024/06/16 17:37
Bellmen算法是求最短路径的最方便的算法之一,SPFA算法更方便,是Bellmen算法的队列实现但队列不会,掌握Bellmen算法即可解决大部分最短路径的问题。Bellmen算法的最大优势就在于可以解决边权值为负的情况。(限于有向图)
另外,Bellmen算法的运算时间为O(nm)适合n^2>m的稀疏图!!!当遇到n^2<m的稠密图时最好用Dijkstra算法,其运算时间为O(n^2)。
典例:给n个点,m条路径,求A点到B点的最短路径。
需要开设dis[]记录,dis[i]即到达i点的最短距离,输出时输出dis[i]即可。
*核心代码:
for(int i=1;i<=n-1;i++) { for(int j=1;j<=m;j++) { if(dis[edge[j].v]>dis[edge[j].u]+edge[j].w) dis[edge[j].v]=dis[edge[j].u]+edge[j].w; } }
理论上一共要进行n-1轮松弛,但有可能最后几轮的松弛将不再改变dis[]中的值,故可以提前结束循环节省运算时间。需要一个与dis[]一样大的数组dis1[]备份dis[]的值,另外还引进一个flag变量初始化为0。每次松弛过后将dis[]与dis1[]中的值一一比对,若相同则flag=1;判断if(flag==1)则结束循环无需再松弛。
#include <iostream>#include<stdio.h>#define max 99999999using namespace std;int dis[200],dis1[200],n,m,a,b;struct node{ int u,v,w; //起点。重点,权值}edge[100];void init() //初始化{ for(int i=1;i<=n;i++) dis[i]=max; //初始化将到达每个点的距离设为无穷 dis[a]=0; //起点开始故距离为0}int main(){ while(cin>>n>>m>>a>>b) { init(); for(int i=1;i<=m;i++) { cin>>edge[i].u>>edge[i].v>>edge[i].w; } //bellmen核心语句!!! int flag; for(int i=1;i<=n-1;i++) { flag=0; for(int j=1;j<=m;j++) { if(dis[edge[j].v]>dis[edge[j].u]+edge[j].w) dis[edge[j].v]=dis[edge[j].u]+edge[j].w; } for(int j=1;j<=n;j++) if(dis[j]!=dis1[j]) { flag=1;dis1[j]=dis[j]; } if(flag==0) break; //若值均未变则跳出循环 } //输出结果 cout<<dis[b]<<endl; } return 0;}
数据:
Input:5 5 1 5
2 3 2
1 2 -3
1 5 5
4 5 2
3 4 3
Output:4
运算过程(理解运算原理)
初始化:dis 1 2 3 4 5
0 max max max max
第一轮:先处理第一条边,2——>3距离为2,此时dis[2]和dis[3]均为max,无法比较,松弛失败。第二条边1——>2距离为-3,此时dis[1]=0,dis[2]=max,dis[2]>dis[1]+(-3),故dis[2]值变为-3。第三条边1——>5距离为5,dis[5]>dis[1]+5,故dis[5]=5。以此方法,第三四条边无法松弛,故第一轮松弛结束。
dis 1 2 3 4 5
0 -3 max max 5
第二轮:处理刚才未松弛成功的第一条边2——>3,dis[3]>dis[2]+(-3),dis[3]=-1。之后3——>4,dis[4]>dis[3]+3,dis[4]=2。发现了从4——5距离会比1——>5短,但松弛3——>4时已经过了4——>5的边,只能再进行一轮松弛。
dis 1 2 3 4 5
0 -3 -1 2 5
第三轮:处理4——>5,dis[5]>dis[4]+2,dis[5]=4。
dis 1 2 3 4 5
0 -3 -1 2 4
第四轮:无变化的值,flag=0,跳出循环。
dis 1 2 3 4 5
0 -3 -1 2 4
- 中级篇——Bellmen算法求最短路径
- 中级篇——Dijkstra算法求最短路径
- 最短路径算法总结(Floyd,bellmen-ford,dijkstra,Spfa)
- 最短路径算法总结(Floyd,bellmen-ford,dijkstra,Spfa)
- Bellmen-Ford算法的应用——杭电OJ 2544 最短路
- 排序算法-中级篇
- 迪杰斯塔拉算法—求最短路径
- JAVA规则——中级篇
- 中级篇——并查集
- 中级篇——最小生成树
- 中级篇——优先队列
- 数据库知识——中级篇
- 彻底搞懂 RxJava — 中级篇
- 【Unity Shader入门精要】— 中级篇
- 排序算法-中级篇(归并排序)
- 求最短路径之——Dijkstra算法
- 求最短路径之——Floyd算法
- java实现普里姆算法—求最短路径
- 百度地图使用问题
- TCP的状态和三次握手
- 第六章 文本分类
- 用SAXReader解析xml文档
- Centos6.5安装配置keepalived
- 中级篇——Bellmen算法求最短路径
- kd-tree的实现
- 网页计算器
- github安装不了问题
- PHP学习-----Android客户端传回图片的base64位码php保存到服务器和文件夹里面
- TCP协议中的三次握手和四次挥手(图解)
- jacobi迭代法(C#实现)
- Android Fragment 真正的完全解析(上)
- python简单小记