#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]);
}