算法思路:每次从未标记的顶点集中选出距离源点距离最短的顶点,然后将此点标记,再通过此顶点对与该点直接相连的顶点进行放缩(若可通过该点缩短缩短与源点的距离,则缩短),直至最后所有顶点都被标记,最后利用path数组输出最短路径。
#include<iostream>
using namespace std;
int a[101][101],d[101],book[101],t,n,MIN,path[101],temp[101],tp;
void Dijkstra(int o){
for(int i=1;i<n;i++){
MIN=999;
for(int j=1;j<=n;j++){
if(book[j]==0&&d[j]<MIN){ //寻找未标记且与源点距离最短的点
t=j;
MIN=a[o][j];
}
}
book[t]=1;
for(int k=1;k<=n;k++){
if(a[t][k]<999&&d[k]>d[t]+a[t][k]){ //放缩
d[k]=d[t]+a[t][k];
path[k]=t; //若可通过点t进行放缩,则点k的前一个顶点即为点t
}
}
}
}
int main(){
int c=0,m,o,k,e,u,v;
cout<<"请输入图中顶点个数"<<endl;
cin>>n;
cout<<"请输入图中边的个数"<<endl;
cin>>m;
cout<<"请构造图"<<endl;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i==j)
a[i][j]=0;
else
a[i][j]=999;
}
while(c<m){
cin>>u>>v>>k;
a[u][v]=k;
a[v][u]=k;
c++;
}
cout<<"请输入源点编号"<<endl;
cin>>o;
book[o]=1;
for(int i=1;i<=n;i++){
d[i]=a[o][i]; //与源点直接相连的点最短距离即为相连边的权值
path[i]=o; //与源点直接相连的点最短路径即为源点到此点
}
Dijkstra(o);
cout<<"请输入终点编号"<<endl;
cin>>e;
cout<<"从源点"<<o<<"到终点"<<e<<"的最短距离为"<<d[e]<<endl;
tp=e;
int i=0;
while(tp!=o){ //用数组temp保存最短路径
temp[i]=tp;
i++;
tp=path[tp];
}
cout<<"最短路径为"<<o;
for(int j=i-1;j>=0;j--){ //输出最短路径
cout<<"-->"<<temp[j];
}
return 0;
}