作为能够判断负权边的算法,效率比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; }