這個題有一個小小的tricky,就是要考慮重邊的情況,如果遇到重復的邊,則直接取最小的邊。
Dijkstra(迪傑斯特拉)算法是典型的最短路徑路由算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。Dijkstra算法能得出最短路徑的最優解,但由於它遍歷計算的節點很多,所以效率低。其基本思想是,設置頂點集合S並不斷地作貪心選擇來擴充這個集合。一個頂點屬於集合S當且僅當從源到該頂點的最短路徑長度已知。
初始時,S中僅含有源。設u是G的某一個頂點,把從源到u且中間只經過S中頂點的路稱為從源到u的特殊路徑,並用數組dist記錄當前每個頂點所對應的最短特殊路徑長度。Dijkstra算法每次從V-S中取出具有最短特殊路長度的頂點u,將u添加到S中,同時對數組dist作必要的修改。一旦S包含了所有V中頂點,dist就記錄了從源到所有其它頂點之間的最短路徑長度。
#include<iostream> using namespace std; const int maxn=205; const int intmax=99999; int weight[maxn][maxn]; //保存權值的鄰接矩陣 int dis[maxn]; int s,t; void dijkstra() { bool Sset[maxn]; memset(Sset,0,sizeof(Sset)); Sset[s]=1; for(int i=0;i<maxn;i++) { int u,v; int tmp=intmax; for(int i=0;i<maxn;i++) { if(!Sset[i]&&dis[i]<tmp) { u=i; tmp=dis[i]; } } Sset[u]=1; for(int i=0;i<maxn;i++) { if(!Sset[i]&&weight[u][i]<intmax) { int newdis=dis[u]+weight[u][i]; if(newdis<dis[i])dis[i]=newdis; } } } } int main() { int n,m; while(cin>>n>>m) { int a,b,x; for(int i=0;i<maxn;i++) for(int j=0;j<maxn;j++) weight[i][j]=intmax; for(int i=0;i<m;i++) { cin>>a>>b>>x; if(x<weight[a][b]) //處理重邊 weight[a][b]=weight[b][a]=x; } cin>>s>>t; for(int i=0;i<maxn;i++)dis[i]=weight[s][i]; dis[s]=0; //如果是起點到起點,則應該是0 dijkstra(); if(dis[t]<intmax) cout<<dis[t]<<endl; else cout<<-1<<endl; //不存的情況應該是:權值無窮大 } return 0; } #include<iostream> using namespace std; const int maxn=205; const int intmax=99999; int weight[maxn][maxn]; //保存權值的鄰接矩陣 int dis[maxn]; int s,t; void dijkstra() { bool Sset[maxn]; memset(Sset,0,sizeof(Sset)); Sset[s]=1; for(int i=0;i<maxn;i++) { int u,v; int tmp=intmax; for(int i=0;i<maxn;i++) { if(!Sset[i]&&dis[i]<tmp) { u=i; tmp=dis[i]; } } Sset[u]=1; for(int i=0;i<maxn;i++) { if(!Sset[i]&&weight[u][i]<intmax) { int newdis=dis[u]+weight[u][i]; if(newdis<dis[i])dis[i]=newdis; } } } } int main() { int n,m; while(cin>>n>>m) { int a,b,x; for(int i=0;i<maxn;i++) for(int j=0;j<maxn;j++) weight[i][j]=intmax; for(int i=0;i<m;i++) { cin>>a>>b>>x; if(x<weight[a][b]) //處理重邊 weight[a][b]=weight[b][a]=x; } cin>>s>>t; for(int i=0;i<maxn;i++)dis[i]=weight[s][i]; dis[s]=0; //如果是起點到起點,則應該是0 dijkstra(); if(dis[t]<intmax) cout<<dis[t]<<endl; else cout<<-1<<endl; //不存的情況應該是:權值無窮大 } return 0; }