這裡來簡單介紹下SPFA演算法。
1、SPFA演算法是求解單源最短路徑的,時間複雜度為0(kn),一般k<2。所以該演算法高效。
2、以下的代碼藉助STL中的vector,用臨界表來儲存圖的。
3、如果要輸出一條最短路徑對應的路線,我們可以用source[]表來記錄。例如source[a]=b,
表示a的前驅為b。這樣在執行完SPFA演算法後,就會得到一張source表。然後從end向前一直,
找到start為止。就可產生一條路徑了。當然,以上所說的只是比較簡單的。比如要求在有多條
路徑時列印經過節點最少的、字典序順序小的。。。
4、SPFA演算法不僅可以判斷有向圖、無向圖任意兩點之間是否有路徑可達,還可以給出實際值。
5、一個關於SPFA演算法的PPT,內容不錯,免積分下載:SPFA演算法簡介
代碼:
#include<iostream>#include<vector>#include<queue>#include<stack> #include<cstring>using namespace std;const int maxn=1001;const int INF=0x7fffffff;struct edge //邊 { int to; int cost;}; vector<edge> myV[maxn]; //利用臨界表格儲存體圖 int numNode,numEdge; //頂點數、邊 int minPath[maxn]; //最短路int source[maxn]; //source[a]=b,說明a的前驅為b int start,end; //起點、終點 bool inQ[maxn]; //是否入隊 void inputItial(){ int i,from,to,cost; for(i=0;i<maxn;i++) //清空再使用 { myV[i].clear(); } for(i=0;i<numEdge;i++) //建圖 ,無向圖 { scanf("%d%d%d",&from,&to,&cost); edge e; e.cost=cost; e.to=to; myV[from].push_back(e); e.to=from; myV[to].push_back(e); }}void output(int start,int end) //輸出 { if(minPath[end]==INF) { printf("No Such Path Exist!\n\n"); } else if(start==end) { printf("From %d to %d :\n",start,end); printf("Path: %d\n",start); printf("Total cost : 0\n\n"); } else { printf("From %d to %d :\n",start,end); printf("Path: %d",start); int tmp=end; stack<int> s; s.push(tmp); while(source[tmp]!=start) { tmp=source[tmp]; s.push(tmp); } while(!s.empty()) { printf("-->%d",s.top()); s.pop(); } printf("\n"); printf("Total cost : %d\n\n",minPath[end]); } } void SPFA(int start,int end) //最短路徑快速演算法 Shortest Path Faster Algorithm{ memset(inQ,false,sizeof(inQ)); inQ[start]=true; for(int j=0;j<maxn;j++) minPath[j]=INF; minPath[start]=0; queue<int> myQ; myQ.push(start); int now,to,cost; while(!myQ.empty()) { now=myQ.front(); myQ.pop(); for(int k=0;k<myV[now].size();k++) { to=myV[now][k].to; cost=myV[now][k].cost+minPath[now]; if(minPath[to]>cost) { source[to]=now; //記錄下to的來源為now minPath[to]=cost; if(!inQ[to]) { inQ[to]=true; myQ.push(to); } } } inQ[now]=false; } output(start,end); } int main(){ while(scanf("%d%d",&numNode,&numEdge)==2,numNode || numEdge) { inputItial(); while(scanf("%d%d",&start,&end)==2,start!=-1 && end!=-1) { SPFA(start,end); } } system("pause"); return 0;}
簡單的小測試: