/****************************/
/* Dijkstra(最短経路) */
/* coded by Y.Suganuma */
/****************************/
#include <stdio.h>
#include <set>
using namespace std;
class Net
{
public :
int node; // ノード番号
int r; // スタートからの距離
Net (int n1, int r1)
{
node = n1;
r = r1;
}
};
bool operator< (Net n1, Net n2)
{
if (n1.r == n2.r)
return (n1.node < n2.node) ? true : false;
else
return (n1.r < n2.r) ? true : false;
}
/********************************************/
/* Dijkstra(最短経路) */
/* n : ノードの数 */
/* ノード0:スタート */
/* ノード(n-1):ゴール */
/* r : ノード間の距離 */
/* rd : 現時点におけるノードまでの距離 */
/* used : 距離が確定したか否か */
/********************************************/
void Dijkstra(int n, int **r, int *rd, bool *used)
{
int i1, k, v, r1, node = 1;
set<Net> s;
set<Net>::iterator it;
s.insert(Net(0, 0));
while (!s.empty()) {
it = s.begin();
k = it->node;
v = it->r;
if (!used[k]) {
// 先頭のノードから到達可能なノードをセットに追加
// ・距離が決定しているノードは除く
// ・既にノードまでの距離が計算済みであり,その距離が
// 今回計算した距離よりも短い場合は距離を修正して追加
used[k] = true;
for (i1 = 0; i1 < n; i1++) {
if (!used[i1] && r[k][i1] >= 0) {
r1 = v + r[k][i1];
if (rd[i1] < 0 || r1 < rd[i1]) {
s.insert(Net(i1, r1));
rd[i1] = r1;
node++;
}
}
}
}
else
node--;
s.erase(it);
}
printf("展開したノード数: %d, 最短距離: %d\n", node, rd[n-1]);
}
int main()
{
int i1, i2, **r, *rd;
bool *used;
used = new bool [7];
rd = new int [7];
r = new int * [7];
for (i1 = 0; i1 < 7; i1++) {
used[i1] = false;
rd[i1] = -1;
r[i1] = new int [7];
for (i2 = 0; i2 < 7; i2++)
r[i1][i2] = -1;
}
rd[0] = 0;
r[0][1] = 2;
r[1][0] = 2;
r[0][2] = 5;
r[2][0] = 5;
r[1][2] = 4;
r[2][1] = 4;
r[1][3] = 6;
r[3][1] = 6;
r[1][4] = 10;
r[4][1] = 10;
r[2][3] = 2;
r[3][2] = 2;
r[3][5] = 1;
r[5][3] = 1;
r[4][5] = 3;
r[5][4] = 3;
r[4][6] = 5;
r[6][4] = 5;
r[5][6] = 9;
r[6][5] = 9;
Dijkstra(7, r, rd, used);
return 0;
}
-----------------set を使用しない方法----------------
#include <stdio.h>
/********************************************/
/* Dijkstra(最短経路) */
/* n : ノードの数 */
/* ノード0:スタート */
/* ノード(n-1):ゴール */
/* r : ノード間の距離 */
/* rd : 現時点におけるノードまでの距離 */
/* used : 距離が確定したか否か */
/* coded by Y.Suganuma */
/********************************************/
void Dijkstra(int n, int **r, int *rd, bool *used)
{
int i1, r1, node = 1, nx, next = 0;
while (next >= 0) {
// 先頭のノードから到達可能なノードを調べる
// ・距離が決定しているノードは除く
// ・既にノードまでの距離が計算済みであり,その距離が
// 今回計算した距離よりも短い場合は距離を修正して追加
nx = next;
next = -1;
used[nx] = true;
for (i1 = 0; i1 < n; i1++) {
if (!used[i1]) {
if (r[nx][i1] >= 0) {
r1 = rd[nx] + r[nx][i1];
if (rd[i1] < 0 || r1 < rd[i1]) {
rd[i1] = r1;
node++;
}
}
if (next < 0 || rd[i1] >= 0 && rd[i1] < rd[next])
next = i1;
}
}
}
printf("計算したノード数: %d, 最短距離: %d\n", node, rd[n-1]);
}
int main()
{
int i1, i2, **r, *rd;
bool *used;
used = new bool [7];
rd = new int [7];
r = new int * [7];
for (i1 = 0; i1 < 7; i1++) {
used[i1] = false;
rd[i1] = -1;
r[i1] = new int [7];
for (i2 = 0; i2 < 7; i2++)
r[i1][i2] = -1;
}
rd[0] = 0;
r[0][1] = 2;
r[1][0] = 2;
r[0][2] = 5;
r[2][0] = 5;
r[1][2] = 4;
r[2][1] = 4;
r[1][3] = 6;
r[3][1] = 6;
r[1][4] = 10;
r[4][1] = 10;
r[2][3] = 2;
r[3][2] = 2;
r[3][5] = 1;
r[5][3] = 1;
r[4][5] = 3;
r[5][4] = 3;
r[4][6] = 5;
r[6][4] = 5;
r[5][6] = 9;
r[6][5] = 9;
Dijkstra(7, r, rd, used);
return 0;
}