数据结构课图作业之最短路:打印出从某个源点到其余所有顶点的具体路径和其最小路径长度。在整个算法中只要加上一个pre数组保存i点直接前驱即可。另在输出路径函数中,首先从终点往前推到起点(pre数组可以保证),并把沿途的点都加入到一个栈中。然后输出整个栈即是一条路径。
#include <iostream>
using namespace std;
#define N 100
#define INF 0x3f3f3f3f
#define _clr(x, y) memset(x, y, sizeof (x))
int dist[N], prev[N];
int map[N][N];
bool used[N];
int n;
void Dijkstra(int s)
{
_clr(dist, INF);
for(int i=1; i<=n; ++i)
{
dist[i] = map[s][i];
used[i] = 0;
if(dist[i] == INF)
prev[i] = 0;
else
prev[i] = s;
}
dist[s] = 0;
used[s] = true;
for(int i=1; i<=n; ++i)
{
int tmp = INF;
int u = s;
for(int j=1; j<=n; ++j)
if(!used[j] && dist[j]<tmp)
tmp = dist[u = j];
used[u] = true;
for(int j=1; j<=n; ++j)
if(!used[j] && map[u][j]<INF)
{
int t = dist[u] + map[u][j];
if(t < dist[j])
{
dist[j] = t;
prev[j] = u;
}
}
}
}
// 打印s->的路径
void ShowPath(int s, int u)
{
if(dist[u]==INF)
{
cout << "******** 无法到达 *********
";
return;
}
int Sta[N];
int top = 1;
Sta[top++] = u;
int tmp = prev[u];
while(tmp != s)
{
Sta[top++] = tmp;
tmp = prev[tmp];
}
Sta[top] = s;
while(top!=1)
{
cout << Sta[top--] << " -> ";
}
cout << Sta[top];
cout << " : " << dist[u] << endl;
}
int main()
{
int m, a, b, d;
while(cin >> n >> m)
{
_clr(map, INF);
for(int i=1; i<=n; ++i) map[i][i] = 0;
for(int i=1; i<=m; ++i)
{
cin >> a >> b >> d;
if(d < map[a][b])
map[a][b] = map[b][a] = d;
}
cin >> a;
Dijkstra(a);
cout<<"源点到各个顶点的路径和路程如下:
";
for(int i=1; i<=n; i++) if(i!=a)
{
cout<< a << " 到 "<< i << "的路劲如下:
";
ShowPath(a, i);
}
}
return 0;
}