SPFA是用隊列處理Bellman-Ford算法,效率很高。但他並不穩定。c++
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 }