SPFA是用队列处理Bellman-Ford算法,效率很高。但他并不稳定。
1 #include<bits/stdc++.h>
2 using namespace std;
3
4 const int inf = 0x3f3f3f3f;
5 const int num = ???;
6 struct edge{
7 int from, to, w;//边:起点from(其实没有用到),终点to,权值(距离)w
8 edge(int a, int b, int c){from=a; to=b; w=c;}
9 };
10 vector<edge>e[num];//第i个节点连接的所有边
11 int n, m;
12 int dis[num];//从规定起点到点i的距离
13 int pre[num];//记录路径
14
15 //打印路径
16 void print_path(int s, int t){
17 if(s == t){printf("%d",s); return ;}
18 print_path(s, pre[t]);
19 printf("->%d",t);
20 }
21
22 int spfa(int s){
23 bool inq[num];//标记节点i是否在队列中
24 int neg[num];//判断负圈
25 //初始化
26 for(int i=1; i<=n; i++){
27 neg[i] = 0;
28 dis[i] = inf;
29 inq[i] = false;
30 }
31 neg[s] = 1;
32 //
33 queue<int>q;
34 q.push(s);
35 inq[s] = true;//s进队
36 //
37 while(!q.empty()){
38 int u = q.front();
39 q.pop();
40 inq[u] = false;//s出队
41
42 for(int i=0; i<e[u].size(); i++){//检查节点u连接的所有边
43 int v = e[u][i].to, w = e[u][i].w;
44 if(dis[u] + w < dis[v]){//起点->u->v的距离 < 起点->v的距离
45 dis[v] = dis[u] + w;
46 pre[v] = u;
47 if(!inq[v]){//如果v不在队列则插入
48 inq[v] = true;
49 q.push(v);
50 neg[v]++;
51 if(neg[v] > n) return 1;//v的更新次数超过节点个数,则说明存在负圈
52 }
53 }
54 }
55 }
56 //print_path(s,?);
57 return 0;
58 }
59
60 int main(){
61 while(~scanf("%d %d", &n, &m) && n && m){
62 for(int i=1; i<=n; i++) e[i].clear();
63 while(m--){
64 int a, b, c;
65 scanf("%d %d %d", &a, &b, &c);
66 e[a].push_back(edge(a,b,c));
67 e[b].push_back(edge(b,a,c));
68 }
69 spfa(1);//规定1为起点
70 }
71 return 0;
72 }
来源:https://www.cnblogs.com/0424lrn/p/12241950.html