SPFA单源最短路径算法(利用队列优化过的Bellman-Ford算法)

Bellman-Ford算法时间复杂度达到了O(VE),那么可不可以对Bellman-Ford算法进行优化呢?

 

首先思考:Bellman-Ford算法很大一部分时间都用来做了无效功,其实,只有当dis[u]的值改变的时候,才可能使得以u为中介点到达v的dis[v]变短,从而进行松弛操作,那么一个办法就是:当dis[u]改变,则对以u出发能够到达的顶点V1、V2、V3,,,的这些边进行松弛操作。自然想到可以利用队列进行优化,即将u加入到队列里边,,,

 

代码如下:

queue<int> q;
int hashtable[maxn] = { false };//哈希表判断顶点v是否被加入了队列
int innum[maxn] = { 0 };//记录被加入队列的次数
bool SPFA(int s) {
	dis[s] = 0;
	q.push(s);
	hashtable[s] = true;//标志被加入队列
	innum[s]++;
	while (q.empty() == false) {//队列非空
		int u = q.front();//取出队首元素
		hashtable[u] = false;
		for (int i = 0; i < adj[u].size(); i++) {
			int v = adj[u][i].v;
			int distance = adj[u][i].weight;
			if (dis[u] + distance < dis[v]) {//进行松弛操作
				dis[v] = dis[u] + distance;
				if (hashtable[v] == false) {//如果v还未被加入队列
					q.push(v);
					hashtable[v] = true;
					innum[v]++;
					if (innum[v] > Vertexnum - 1) {//如果v加入队列的次数大于Vertaxnum-1,说明有可达的负环
						return false;
					}
				}
			}
		}
	}
}

SPFA算法期望的时间复杂度为:O(KE),E是图的边数,K是一个常数,可以看出,它是非常优秀的。此SPFA算法可判断是否有可达的负环,并不能判断图中是否有负环;如果图中有源点可达的负环,则SPFA算法时间复杂度退化为O(VE),SPFA算法我本身还有很多没有理解的地方,以后再进行补充

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/qq_39034748/article/details/81022739
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞