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