1.主な手順
1.ソースポイントv0から他のポイントへの直接パスを見つけ、それをdist配列に記録します。dist[i]はv0からviまでの距離を表します。v0からviへの直接アクセスがない場合は、dist [i]を無限大Maxとして記録します。
2.訪問されておらず、v0からの距離が最も短いdist配列内の点uを見つけます。
3.uを介してdist配列を更新します。v0からuを介してviまでの距離がdist [i]よりも小さい場合は、dist [i]をdist [u] + edge [u] [i]に更新します。
4.手順2と3をn-1回続行します。このとき、dist [i]はv0からviまでの最短距離を表します。
2.例
図に示すように、v0から他のポイントへの最短経路を見つけます。まず、dist配列を初期化します。dist[1] = 13、dist [2] = 18、dist [3] = Max、dist [4] = 30、dist [5] = Max、dist [6] = 32;
最短のエッジdist [2] = 8を見つけ、v0からvi、v0からv2、次にviまでの距離を比較し、dist [2] + edge [2] [3] = 8であるため、dist [i]を更新します。 + 5 = 13 <dist [3] =最大であるため、dist [3]は13に更新されます。
最短のエッジdist [1] = 13を探し続け、v0からviまで、v0からv1まで、次にviまでの距離を比較し、dist [1] + edge [1] [5]であるため、dist [i]を更新します。 = 13 +9 = 22 <dist [5] =最大であるため、dist [5]は22に更新されます。同様に、dist [6]は20に更新されます。
n-1回まで操作を続けると、アルゴリズムは終了します。
3.コードの実装
#include<iostream>
using namespace std;
#define Max 9999
int n, m;
bool visited[Max];
int edge[Max][Max];
int dist[Max];
void Dijkstra()
{
visited[0] = true;
int min = Max;
int index = 0;
for (int i = 0; i < n-1; ++i)
{
min = Max;
for (int j = 0; j < n; ++j)
{
if (!visited[j] && dist[j] < min) //寻找最短边
{
min = dist[j];
index = j;
}
}
visited[index] = true;
for (int j = 0; j < n; ++j)
{
if (!visited[j] && dist[index] + edge[index][j] < dist[j]) //比较从v0经过u再到达vi的距离和dist[i]的大小
{
dist[j] = dist[index] + edge[index][j];
}
}
}
for (int i = 1; i < n; ++i)
{
cout << dist[i] << " ";
}
}
int main()
{
cout << "输入节点数: ";
cin >> n;
cout << "输入边数:";
cin >> m;
fill(edge[0], edge[0] + Max*Max, Max); //初始化各个数组
fill(dist, dist + n, Max);
fill(visited, visited + n, false);
int u, v, w;
cout << "输入各条边的信息:" << endl;
for (int i = 0; i < m; ++i)
{
cin >> u >> v >> w;
edge[u][v] = edge[v][u] = w;
}
dist[0] = 0;
for (int i = 1; i < n; ++i) //初始化从v0到其他各点的距离
{
dist[i] = edge[0][i];
}
Dijkstra();
return 0;
}
入力および出力情報: