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算法我本身还有很多没有理解的地方,以后再进行补充