用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。Dijkstra算法能得出最短路徑的最優解,但由於它遍歷計算的節點很多,所以效率低。
基本介紹
- 中文名:最短路徑
- 外文名:shortest path
- 性質:一類經典算法問題
- 解決思路:由已知點/邊向外擴展
- 解決方法:SPFA算法、Dijkstra算法等
最短路徑介紹
解決方法
最短路徑算法
#include<iostream>#include<vector>using namespace std;void dijkstra(const int &beg,//出發點 const vector<vector<int> > &adjmap,//鄰接矩陣,通過傳引用避免拷貝 vector<int> &dist,//出發點到各點的最短路徑長度 vector<int> &path)//路徑上到達該點的前一個點//負邊被認作不聯通//福利:這個函式沒有用任何全局量,可以直接複製!{ const int &NODE=adjmap.size();//用鄰接矩陣的大小傳遞頂點個數,減少參數傳遞 dist.assign(NODE,-1);//初始化距離為未知 path.assign(NODE,-1);//初始化路徑為未知 vector<bool> flag(NODE,0);//標誌數組,判斷是否處理過 dist[beg]=0;//出發點到自身路徑長度為0 while(1) { int v=-1;//初始化為未知 for(int i=0; i!=NODE; ++i) if(!flag[i]&&dist[i]>=0)//尋找未被處理過且 if(v<0||dist[i]<dist[v])//距離最小的點 v=i; if(v<0)return;//所有聯通的點都被處理過 flag[v]=1;//標記 for(int i=0; i!=NODE; ++i) if(adjmap[v][i]>=0)//有聯通路徑且 if(dist[i]<0||dist[v]+adjmap[v][i]<dist[i])//不滿足三角不等式 { dist[i]=dist[v]+adjmap[v][i];//更新 path[i]=v;//記錄路徑 } }}int main(){ int n_num,e_num,beg;//含義見下 cout<<"輸入點數、邊數、出發點:"; cin>>n_num>>e_num>>beg; vector<vector<int> > adjmap(n_num,vector<int>(n_num,-1));//默認初始化鄰接矩陣 for(int i=0,p,q; i!=e_num; ++i) { cout<<"輸入第"<<i+1<<"條邊的起點、終點、長度(負值代表不聯通):"; cin>>p>>q; cin>>adjmap[p][q]; } vector<int> dist,path;//用於接收最短路徑長度及路徑各點 dijkstra(beg,adjmap,dist,path); for(int i=0; i!=n_num; ++i) { cout<<beg<<"到"<<i<<"的最短距離為"<<dist[i]<<",反向列印路徑:"; for(int w=i; path[w]>=0; w=path[w]) cout<<w<<"<-"; cout<<beg<<'\n'; }}