#include < iostream >
using namespace std;
#define NUM 5
#define NIF 999
// 定义图
typedef struct{
int edge[NUM][NUM]; // 各边的指向和权值
int n; // n 为顶点数
}Mgragh;
// 初建图
void initGragh(Mgragh &gh,int a[][NUM])
{
for(int i=0;i<NUM;i++){
for(int j=0;j<NUM;j++){
gh.edge[i][j] = a[i][j];
}
}
gh.n = NUM;
}
void Dijkstra(Mgragh &gh,int v)
{
int u,min;
int i,j;
int dist[NUM],path[NUM], set[NUM]; // path[NUM]保存结点的前面一个结点, set[NUM]表明是否已遍历该节点
// dist[NUM]保存结点到指定结点的最短距离
// 初始化其余每一个结点的信息
for(i=0;i<gh.n;i++){
dist[i] = gh.edge[v][i];
set[i] = 0;
if(gh.edge[v][i]<NIF) // 每个结点与 v 是否有直接的关系
path[i] = v;
else path[i] = -1;
}
// 重新定义顶点的信息
dist[v] = 0;
set[v] = 1;
path[v] = -1;
for(i=0;i<gh.n-1;i++){ // 逐步连入其余 n-1 个结点
min = NIF;
// min 用来保存权值最小的边
for(j=0;j<gh.n;j++){
if(set[j]==0 && dist[j]<min){ // 寻找权值最小的边的权值
u = j; // 保存结点的下标
min = dist[u]; // min 记录此时权值最小的边的权值(可以用来求最短路径长度)
}
}
set[u] = 1; // 将 u 连入树中
for(j=0;j<gh.n;j++){ // 修改此时每个结点到制定结点的最短路径
if(dist[j]>dist[u]+gh.edge[u][j]){
dist[j] = dist[u]+gh.edge[u][j];
path[j] = u; // 修改前一个结点
}
}
}
int stack[NUM],top=-1; // 建立简易的栈
for(i=0;i<gh.n;i++){
if(i!=v) { // 除初始结点之外的顶点的个单源最短路径
j=i;
while(path[j]!=-1){
stack[++top] = j; // 进栈
j = path[j]; // a指向它的前一个结点
}
stack[++top] = j; // 再将初始结点入栈 , 一般是题目中指定的节点
while(top!=-1){ // 若栈非空,循环
cout<<stack[top--]<<" "; // 全部出栈,依次输出结点的值
}
cout<<":"<<dist[i]<<endl;
}
}
}
int main()
{
int a[][NUM] = { 0, 10,NIF, 30,100,
NIF, 0, 50,NIF,NIF,
NIF,NIF, 0,NIF, 10,
NIF,NIF, 20, 0, 60,
NIF,NIF,NIF,NIF, 0 }; // 下标即为结点内的值
Mgragh gh;
initGragh(gh,a);
Dijkstra(gh,0);
return 0;
}