#include<iostream>
using namespace std;
const int maxnum = 100;
const int maxint = 999999;
//各数组都从下标1开始
int dist[maxnum];
int prec[maxnum];
int c[maxnum][maxnum];
int n, line;
void Dijkstra(int n,int v, int *dist, int *prec, int c[maxnum][maxnum])
{
bool s[maxnum];
for (int i = 1; i <= n;i++)
{
dist[i] = c[v][i];
s[i] = 0;
if (dist[i] == maxint)
{
prec[i] = 0;
}
else
prec[i] = v;
}
dist[v] = 0;
s[v] = 1;
//依次将未放入S集合的节点中,取dist[]最小值的节点,放入集合s中,
//一旦S包含了所有V中顶点,dist就记录了从源点到其他顶点之间的最短路径长度
//注意是从第二个节点开始,因为第一个节点为源点.
for (int i = 2; i <= n;i++)
{
int tmp = maxint;
int u = v;
//找出当前未使用的点j的dist[j]的最小值
for (int j = 1; j <=n; j++)
{
if ((!s[j]) && dist[j]<tmp)
{
u = j;
tmp = dist[j];
}
}
s[u] = 1; //表明u点已存入S集合中
//更新dist
for (int j = 1; j <= n;j++)
{
if (!s[j]&&c[u][j]<maxint)
{
int newdist = dist[u] + c[u][j];
if (newdist<dist[j])
{
dist[j] = newdist;
prec[j] = u;
}
}
}
}
}
//查找从源点v到终点u的路径,并输出
void searchPath(int *prev, int v, int u)
{
int que[maxnum];
int tot = 1;
que[tot] = u;
tot++;
int tmp = prec[u];
while (tmp!=v)
{
que[tot] = tmp;
tot++;
tmp = prec[tmp];
}
que[tot] = v;
for (int i = tot; i >= 1;i--)
{
if (i != 1)
{
cout << que[i] << "-->";
}
else
cout << que[i] << endl;
}
}
//测试程序:
int main()
{
//freopen_s("input.txt", "r", stdin);//各数组下标都从1开始
//现在输入节点数
cin >> n;
//现在输入路径数
cin >> line;
int p, q, len;
//初始化c[][]为maxint
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= n;j++)
{
c[i][j] = maxint;
}
}
for (int i = 1; i <= line;i++)
{
cin >> p >> q >> len;
if (len<c[p][q])
{
c[p][q] = len;
c[q][p] = len;
}
}
for (int i = 1; i <= n;i++)
{
dist[i] = maxint;
}
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= n;j++)
{
printf("%8d", c[i][j]);
}
printf("\n");
}
Dijkstra(n, 1, dist,prec, c);
cout << "源点到最后一个顶点的最短路径长度: " << dist[n] << endl;
// 路径
cout << "源点到最后一个顶点的路径为: ";
searchPath(prec, 1, n);
}
## 补充 ##
总的来说Dijkstra算法还是不简单的,下面的代码是我在网上找的比较精简的算法解决方案
/*
* Dijkstra最短路径。
* 即,统计图(G)中"顶点vs"到其它各个顶点的最短路径。
*
* 参数说明:
* G -- 图
* vs -- 起始顶点(start vertex)。即计算"顶点vs"到其它顶点的最短路径。
* prev -- 前驱顶点数组。即,prev[i]的值是"顶点vs"到"顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。
* dist -- 长度数组。即,dist[i]是"顶点vs"到"顶点i"的最短路径的长度。
*/
typedef struct _graph
{
char vexs[MAX]; // 顶点集合
int vexnum; // 顶点数
int edgnum; // 边数
int matrix[MAX][MAX]; // 邻接矩阵
}Graph, *PGraph;
void dijkstra(Graph G, int vs, int prev[], int dist[])
{
int i,j,k;
int min;
int tmp;
int flag[MAX]; // flag[i]=1表示"顶点vs"到"顶点i"的最短路径已成功获取。
// 初始化
for (i = 0; i < G.vexnum; i++)
{
flag[i] = 0; // 顶点i的最短路径还没获取到。
prev[i] = 0; // 顶点i的前驱顶点为0。
dist[i] = G.matrix[vs][i];// 顶点i的最短路径为"顶点vs"到"顶点i"的权。
}
// 对"顶点vs"自身进行初始化
flag[vs] = 1;
dist[vs] = 0;
// 遍历G.vexnum-1次;每次找出一个顶点的最短路径。
for (i = 1; i < G.vexnum; i++)
{
// 寻找当前最小的路径;
// 即,在未获取最短路径的顶点中,找到离vs最近的顶点(k)。
min = INF;
for (j = 0; j < G.vexnum; j++)
{
if (flag[j]==0 && dist[j]<min)
{
min = dist[j];
k = j;
}
}
// 标记"顶点k"为已经获取到最短路径
flag[k] = 1;
// 修正当前最短路径和前驱顶点
// 即,当已经"顶点k的最短路径"之后,更新"未获取最短路径的顶点的最短路径和前驱顶点"。
for (j = 0; j < G.vexnum; j++)
{
tmp = (G.matrix[k][j]==INF ? INF : (min + G.matrix[k][j])); // 防止溢出
if (flag[j] == 0 && (tmp < dist[j]) )
{
dist[j] = tmp;
prev[j] = k;
}
}
}
// 打印dijkstra最短路径的结果
printf("dijkstra(%c): \n", G.vexs[vs]);
for (i = 0; i < G.vexnum; i++)
printf(" shortest(%c, %c)=%d\n", G.vexs[vs], G.vexs[i], dist[i]);
}