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
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞