ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

最短路径(三):SPFA算法

2021-04-05 20:59:08  阅读:144  来源: 互联网

标签:dist weight int 算法 最短 ++ SPFA num inQueue


Bellman-Ford算法中每轮算操作都需要操作所有边忙着其中会有大量无意义的操作,严重影响算法的性能。仔细思考我们可以发现,只有当某个顶点u的dist[u]值改变时,从u出发的边的邻接点v的dist[v]值才会发生改变。因此可以对Bellman-Ford算法进行如下优化:
建立一个队列,每次将队首顶点u取出,然后对从u出发的所有边进行松弛操作,判断 d i s t [ u ] + w e i g h t [ u ] [ v ] < d i s t [ v ] dist[u]+weight[u][v]<dist[v] dist[u]+weight[u][v]<dist[v]是否成立,如果成立则 d i s t [ v ] = d i s t [ u ] + w e i g h t [ u ] [ v ] dist[v]=dist[u]+weight[u][v] dist[v]=dist[u]+weight[u][v]。此时如果v不在队列中就把v加入到队列中。这样操作直到队列为空。如果某个顶点的入队次数超过V-1,说明图中存在负环(Bellman-Ford算法中只有V-1次)。
实现代码

#include<iostream>
#include<vector>
#include<queue>
using namespace std;

#define MAXV 1000
#define INF 10000
struct Node {
	int source;
	int des; //终点 
	int weight; //权值 
};

vector<Node> Adj[MAXV]; //相当于一个二维数组 
int n; //顶点数 
int dist[MAXV];
int num[MAXV]; //记录入队列的次数
int inQueue[MAXV];

bool SPFA(int s) {
	for (int i = 0; i < n; i++) {
		dist[i] = INF;
		num[i] = 0;
		inQueue[i] = false;
	}
	dist[s] = 0;
	queue<int> Q;
	Q.push(s);
	num[s]++;
	inQueue[s] = true;
	while (!Q.empty())
	{
		int u = Q.front();
		Q.pop();
		inQueue[u] = false;
		for (int j = 0; j < Adj[u].size(); j++) {
			int v = Adj[u][j].des;
			if (dist[u] + Adj[u][j].weight < dist[v]) {
				dist[v] = dist[u] + Adj[u][j].weight;
				if (!inQueue[v]) {
					Q.push(v);
					inQueue[v] = true;
					num[v]++;
					if (num[v] >= n) {
						return false;
					}
				}
			}
		}
	}
	return true;
}


int main() {
	cin >> n;
	for (int i = 0; i < n; i++) {
		int num;
		cin >> num;
		for (int j = 0; j < num; j++) {
			int source,des, weight;
			cin >> source>>des >> weight;
			Node node = {source,des,weight };
			Adj[source].push_back(node);
		}
	}
	if (SPFA(0)) {
		for (int i = 0; i < n; i++) {
			cout << dist[i] << " ";
		}
	}
	else {
		cout << "该图不存在最短路径" << endl;
	}
	return 0;
}

标签:dist,weight,int,算法,最短,++,SPFA,num,inQueue
来源: https://blog.csdn.net/qq_43406565/article/details/115447469

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有