作为能够判断负权边的算法,效率比Bellman-Ford要高,比较实用

参考博客:
http://keyblog.cn/article-21.html

https://blog.csdn.net/sxy201658506207/article/details/78779045

 

使用邻接矩阵

spfa算法模板(邻接矩阵):
c++ code:
void spfa(int s){
    for(int i=0; i<=n; i++) dis[i]=99999999; //初始化每点i到s的距离
    dis[s]=0; vis[s]=1; q[1]=s;  队列初始化,s为起点
    int i, v, head=0, tail=1;
    while (head<tail){   队列非空
        head++; 
        v=q[head];  取队首元素
        vis[v]=0;   释放队首结点,因为这节点可能下次用来松弛其它节点,重新入队
        for(i=0; i<=n; i++)  对所有顶点
           if (a[v][i]>0 && dis[i]>dis[v]+a[v][i]){  
                dis[i] = dis[v]+a[v][i];   修改最短路
                if (vis[i]==0){  如果扩展结点i不在队列中,入队
                    tail++;
                    q[tail]=i;
                    vis[i]=1;
                }
           }
        
    }
}

使用深搜进行优化

#include <iostream>
using namespace std;
int q[10001], dis[201], a[201][201], b[201][201];
bool vis[201];
int n, m, s, t;
void spfa(int s)
{
    for(int i=1; i<=b[s][0]; i++)
        if (dis[b[s][i]] > dis[s]+a[s][b[s][i]])
        {
                dis[b[s][i]] = dis[s]+a[s][b[s][i]];
                spfa(b[s][i]);
        }
}
int main()
{
    int x, y, z;
    cin >> n >> m; 
    for(int i=0; i<m; i++)
    {
        cin >> x >> y >> z;  
        if (a[x][y]!=0 && z>a[x][y]) continue;
        b[x][0]++; b[x][b[x][0]]=y; a[x][y]=z; 
        b[y][0]++; b[y][b[y][0]]=x; a[y][x]=z;
    }
    cin >> s >> t;
    for(int i=0; i<=n; i++) dis[i]=99999999;
    dis[s]=0;
    spfa(s);
    if (dis[t]!=99999999) cout << dis[t] << endl;
    else cout << -1 << endl;
    return 0;
}