-给定一个带权有向图G=(V,E),每条边的权都是非负实数。给定V中一个顶点v为源。计算从源到其他所有顶点的最短路长度。
-Dijkstra算法,贪心算法。
-基本思想:
设置顶点集合S并不断的做贪心选择来扩充这个集合。
(把从源v到u且中间只经过S中顶点的路程为源v到u的特殊路径)
-算法描述:
输入的有向图是G=(V,E),V={1,2,...,n}。
顶点v是源。
power_of_edge[i][j] 表示边(i,j)的权。若(i,j)不属于E,则power_of_edge[i][j] = maxint
min_distance[i] 表示当前从源到顶点i的最短特殊路径长度。
last_vertex[i] 记录从源到i的最短特殊路径上i的上一个顶点。
-以下是我的代码(看书的时候还是挺痛苦的因为书上用的都是u,v,c,n之类的,为了增强可读性,我在自己手打时用了我认为比较好理解的名字):
1 //dijkstra算法 2 //单源最短路径问题 3 4 template <class type> 5 void dijkstra(int num_of_vertexes, int v, type min_distance[], int last_vertex[], type **power_of_edge) 6 { 7 bool has_been_visited[n+1]; 8 for (int i = 1; i <= n; i++) 9 { 10 min_distance[i] = power_of_edge[v][i]; 11 has_been_visited[i] = false; 12 if (min_distance[i] == maxint) last_vertex[i] = 0; 13 else last_vertex[i] = v; 14 } 15 has_been_visited[v] = true; 16 min_distance[v] = 0; 17 for (int i = 1; i < n; i++) 18 { 19 int vertex_will_be_visited_this_time = v; 20 int min_distance_of_the_vertex_will_be_visited_this_time = maxint; 21 for (int j = 1; j <= n; j++) 22 { 23 if ((!has_been_visited[j])&&(min_distance[j]<min_distance_of_the_vertex_will_be_visited_this_time)) 24 { 25 vertex_will_be_visited_this_time = j; 26 min_distance_of_the_vertex_will_be_visited_this_time = min_distance[j]; 27 } 28 } 29 has_been_visited[vertex_will_be_visited_this_time] = true; 30 for (int j = 1; j <= n; j++) 31 { 32 if ((!has_been_visited[j])&&(power_of_edge[vertex_will_be_visited_this_time][j]<maxint)) 33 { 34 if (min_distance_of_the_vertex_will_be_visited_this_time+power_of_edge[vertex_will_be_visited_this_time][j]<min_distance[j]) 35 { 36 last_vertex[j] = vertex_will_be_visited_this_time; 37 min_distance[j] = min_distance_of_the_vertex_will_be_visited_this_time+power_of_edge[vertex_will_be_visited_this_time][j]; 38 } 39 } 40 } 41 } 42 }