栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

简单算法-bellman最短路

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

简单算法-bellman最短路

一、什么是bellman-ford算法?
       上篇讲到了Floyd算法,它是多源最短路径算法。这里讲的bellman 则是单源最短路径算法。该算法优化了Floyd那样广撒网的形式,一定程度上减小了时间复杂度。能够计算更大图,但缺点是一次只能计算一个结点到各结点对距离。

二、算法思维

       先初始化单源点到其他结点的距离为INF(无穷大),比如我们想要到达一个地方,但我们并不知道有多远,但我们知道去下个地点的距离,我们是不是可以询问下个地点的人去我们要去的地点的距离,也许他也不知道,但他也可以问他下个地点的人,我们只需要记录累加每次询问后距离,就得到了从开始点到每个地点的距离。核心代码:循环检查(单源点到一条边的起始点的距离)与(单源点到这条边结尾点的额距离 + 这条边的权值)的大小,若前者大于后者,说明单源点直接到一边的起始点的距离 比 借助中间结点的距离要大,我们就要将前者的值替换成后者的值。(d[x] = d[y] + e[i].w)。最坏每次循环只能更新一个结点的值,所以最少循环n次。

三、代码实现

     用结构体存边信息。

#include 
#include 
using namespace std;
const int MAX = 1005;
const int INF = 0x3fffffff;

struct Edge {
	int s, e, w;
}r[1005];
int n, m, k, s, cnt;
int d[1006];      //单源点到各点的距离

void bellman() {
	s = 1;
	for (int i = 0; i < MAX; i++) {
		d[i] = INF;
	}
	d[s] = 0;      //s为单源点
	for (int k = 1; k <= n; k++) {    //n轮循环
		for (int i = 1; i < cnt; i++) {    //检查每条边
			int x = r[i].s;  int y = r[i].e;
			if (d[x] > d[y] + r[i].w)
				d[x] = d[y] + r[i].w;
		}
	}
}
int main() {
	int a, b, c;
	while (cin >> n >> m) {
		cnt = 0;
		for (int i = 1; i <= m; i++) {
			cin >> a >> b >> c;
			r[cnt].s = a; r[cnt].e = b; r[cnt++].w = c;
			r[cnt].s = b; r[cnt].e = a; r[cnt++].w = c;
		}
		bellman();
		for (int i = 1; i <= n; i++)
			cout << d[i] << " ";
		cout << endl;
	}
	system("pause");
	return 0;
}

四、输出最短路径

       通过借助中间结点得到最短路径,可以借助数组记录单源点到该结点的最后一个结点,例如:(1,4)是通过(1,3) + (3,4),我们可以知道(1,4)的最后一次经过的结点是3,所以pre[4]=3;同理,(1,3)是通过(1,2) + (2,3),我们可以知道(1,3)的最后一次经过的结点是2。

五、代码实现

#include 
#include 
using namespace std;
const int MAX = 1005;
const int INF = 0x3fffffff;

struct Edge {
	int s, e, w;
}r[1005];
int n, m, k, s, cnt;
int d[1006];      //单源点到各点的距离
int pre[1005];
void bellman() {
	s = 1;
	for (int i = 0; i < MAX; i++) {
		d[i] = INF;
	}
	d[s] = 0;      //s为单源点
	for (int k = 1; k <= n; k++) {    //n轮循环
		for (int i = 1; i < cnt; i++) {    //检查每条边
			int x = r[i].s;  int y = r[i].e;
			if (d[x] > d[y] + r[i].w) {
				d[x] = d[y] + r[i].w;
				pre[x] = y;     //记录路径
			}
		}
	}
} 
void print(int e,int t) {           //输出路径
	if(pre[e] != s) print(pre[e],t);
	cout << pre[e] << "-->";
	if (e == t) cout << e << endl;
}
int main() {
	int a, b, c;
	while (cin >> n >> m) {
		cnt = 0;
		for (int i = 1; i <= m; i++) {
			cin >> a >> b >> c;
			r[cnt].s = a; r[cnt].e = b; r[cnt++].w = c;
			r[cnt].s = b; r[cnt].e = a; r[cnt++].w = c;
		}
		bellman();
		for (int i = 1; i <= n; i++)
			cout << d[i] << " ";
		cout << endl;
		cin >> a;
		print(a, a);
	}
	system("pause");
	return 0;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/296332.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号