基本思想:
每次从当前的最短路径中选出一个,并利用该节点优化图中起始点至图中其它各未访问到的节点的距离。以下图为例,我们欲求出起始点(A)至其它各节点的最短路径:
用数组D来存储A至其它各节点当前路短的距离,例如:D[1]为A-B的当前最短距离,D[2]为A-C当前最短距离。
起始状态为D[0]=0,根据图的连通关系,可以得到:
D[1] = D[0]+L(0->1) = 1
D[2] = D[0]+L(0->2) = 6
D[5] = D[0]+L(0->5) = 10
把D[0]标记为已处理
从未处理过的节点中找出d值最小的节点,由于D[1]=1且B1未被处理过,所以B1为这一步的候选节点,接下来可能得到优化后的D数组:
D[3] = 3
D[4] = 2
将D[1]标记为已处理
同理可以找到最优候选节点E4,优化D数组:
D[5] = Min(D[5], D[4]+1) = 3
选取D3节点:
选取E5节点:
选取C2节点:
处理完成,得到A0到其它任意节点的最短距离
/*
* dijkstra.cc
*
* Created on: Jan 5, 2013
* Author: guixl
*/
#include <stdio.h>
#include <string.h>
const int MAX_VERTEX = 100;
const int INF = 1<<30;
int graph[MAX_VERTEX][MAX_VERTEX];
int d[MAX_VERTEX];
int prefix[MAX_VERTEX];
int visit[MAX_VERTEX];
int vertex_number=6;
void BuildGraph() {
memset(graph, -1, sizeof(graph));
graph[0][1] = 1;
graph[0][2] = 6;
graph[0][5] = 10;
graph[1][3] = 2;
graph[1][4] = 1;
graph[2][3] = 4;
graph[2][4] = 5;
graph[3][5] = 3;
graph[4][5] = 1;
}
void dijkstra() {
for (int i=0; i<vertex_number; i++)
d[i] = i==0 ? 0 : INF;
memset(visit, 0, sizeof(visit));
for (int i=0; i<vertex_number; i++) {
int min_v, min_value=INF;
for (int j=0; j<vertex_number; j++) {
if (d[j]<min_value && !visit[j])
min_value = d[min_v=j];
}
visit[min_v] = 1;
for (int j=0; j<vertex_number; j++)
if (graph[min_v][j] >= 0) {
if(d[min_v]+graph[min_v][j] < d[j]) {
d[j] = d[min_v]+graph[min_v][j];
prefix[j] = min_v;
}
}
}
}
void Print() {
for (int i=0; i<vertex_number; i++) {
printf("Shortest path from 0 to %d is %d:\n", i, d[i]);
for (int s=i; s!=0; s=prefix[s]) {
printf("%d->%d\n", prefix[s], s);
}
}
}
int main(int argc, char** argv) {
BuildGraph();
dijkstra();
Print();
return 0;
}
运行结果:
guixl@guixl-ThinkPad-T61:~/workspace/blog_source_code/src$ ./test
Shortest path from 0 to 0 is 0:
Shortest path from 0 to 1 is 1:
0->1
Shortest path from 0 to 2 is 6:
0->2
Shortest path from 0 to 3 is 3:
1->3
0->1
Shortest path from 0 to 4 is 2:
1->4
0->1
Shortest path from 0 to 5 is 3:
4->5
1->4
0->1