算法思想:(单源最短路径)

  • 1个点到所有其他点的最短路径
  • 查找顶点到其他顶点的最短路径,无法到达的记为+∞,找到最小的,就找到了最短路径的顶点
  • 查看上一轮找到的最小点到达其他点的最小值,找到最短路径的顶点。
  • 以此类推
  • trivial relax:无穷大 ==> 具体数字
  • non-trival relax:具体数字 ==> 具体数

参考:https://www.bilibili.com/video/av36886088


运行效果:

  1. step = 1, minw = 0, pacost[0] = 0.00
  2. trival relax: pacost[1] = inf ==> 1.00
  3. trival relax: pacost[3] = inf ==> 2.00
  4.  
  5. step = 2, minw = 1, pacost[1] = 1.00
  6. trival relax: pacost[2] = inf ==> 4.00
  7.  
  8. step = 3, minw = 3, pacost[3] = 2.00
  9. trival relax: pacost[2] = 4.00 ==> 3.00
  10.  
  11. step = 4, minw = 2, pacost[2] = 3.00
  12.  
  13. visited: {1, 1, 1, 1}
  14. parent: {-1, 0, 3, 0}
  15. pacost: {0.00, 1.00, 3.00, 2.00}

代码:

Dijkstra.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #include "WeGraph.h"
  5.  
  6. void DijkstraPrim(Graph g, int nV, int nE, Vertex src, char alg);
  7.  
  8. int main(){
  9. Graph g = newGraph(4);
  10. Edge e = newEdge(0, 1, 1);
  11. insertEdge(e, g);
  12.  
  13. e = newEdge(1, 2, 3);
  14. insertEdge(e, g);
  15.  
  16. e = newEdge(2, 3, 1);
  17. insertEdge(e, g);
  18.  
  19. e = newEdge(3, 0, 2);
  20. insertEdge(e, g);
  21.  
  22. DijkstraPrim(g, 4, 4, 0, 'd');
  23.  
  24. return 0;
  25. }
  26.  
  27. int *mallocArray(int numV) {
  28. int *array = malloc(numV * sizeof(int));// l
  29. if (array == NULL) { // o
  30. fprintf(stderr, "Out of memory\n"); // c
  31. exit(1); // a
  32. } // l
  33. int i; // f
  34. for (i=0; i<numV; i++) { // u
  35. array[i] = UNVISITED; // n
  36. } // c
  37. return array; // t
  38. }
  39.  
  40. float *mallocFArray(int numV) {
  41. float *array = malloc(numV * sizeof(float));// l
  42. if (array == NULL) { // o
  43. fprintf(stderr, "Out of memory\n"); // c
  44. exit(1); // a
  45. } // l
  46. int i; // f
  47. for (i=0; i<numV; i++) { // u
  48. array[i] = MAXWEIGHT; // n
  49. } // c
  50. return array; // t
  51. }
  52.  
  53. void showArray(char *desc, int *array, int numV) {
  54. int i; // l
  55. printf("%s: {", desc); // o
  56. for (i=0; i<numV; i++) { // c
  57. printf("%d", array[i]); // a
  58. if (i <= numV-2) { // l
  59. printf(", "); // f
  60. } // u
  61. } // n
  62. printf("}\n"); // c
  63. return; // t
  64. }
  65.  
  66. void showFArray(char *desc, float *array, int numV) {
  67. int i; // l
  68. printf("%s: {", desc); // o
  69. for (i=0; i<numV; i++) { // c
  70. printf("%0.2f", array[i]); // a
  71. if (i <= numV-2) { // l
  72. printf(", "); // f
  73. } // u
  74. } // n
  75. printf("}\n"); // c
  76. return; // t
  77. }
  78.  
  79. void DijkstraPrim(Graph g, int nV, int nE, Vertex src, char alg) {
  80. // the last parameter arg is set by main, and is:
  81. // 'd' for Dijkstra or
  82. // 'p' for Prim
  83.  
  84. int *visited = mallocArray(nV); // initialised to UNVISITED
  85. int *parent = mallocArray(nV); // initialised to UNVISITED
  86. float *pacost = mallocFArray(nV); // floats: initialised to INFINITY
  87.  
  88. pacost[src] = 0.0;
  89. for (int step = 1; step <= nV; step++) {
  90.  
  91. printf ("\nstep = %d, ", step);
  92.  
  93. Vertex minw = -1;
  94. for (Vertex w = 0; w < nV; w++) { // find minimum cost vertex
  95. if ((visited[w] == UNVISITED) &&
  96. (minw == -1 || pacost[w] < pacost[minw])) {
  97. minw = w;
  98. }
  99. }
  100.  
  101. printf ("minw = %d, ", minw);
  102. printf ("pacost[%d] = %0.2f\n", minw, pacost[minw]);
  103.  
  104. visited[minw] = VISITED;
  105.  
  106. for (Vertex w = 0; w < nV; w++) { //
  107. Weight minCost = getWeight(g, minw, w);// if minw == w, minCost = NOWEIGHT
  108. // minCost is cost of the minimum crossing edge
  109. if (minCost != NOWEIGHT) {
  110. if (alg == 'd') { // if DIJKSTRA ...
  111. minCost = minCost + pacost[minw];// add in the path cost
  112. }
  113. if ((visited[w] != VISITED) &&
  114. (minCost < pacost[w])) {
  115. printf (" trival relax: pacost[%d] = %0.2f ", w, pacost[w]);
  116.  
  117. pacost[w] = minCost;
  118. parent[w] = minw;
  119.  
  120. printf ("==> %0.2f\n", pacost[w]);
  121. }
  122. }
  123. }
  124.  
  125. }
  126.  
  127. printf("\n");
  128.  
  129. showArray("visited", visited, nV);
  130. showArray("parent", parent, nV);
  131. showFArray("pacost", pacost, nV);
  132. free(visited);
  133. free(parent);
  134. free(pacost);
  135. return;
  136. }

WeGraph.c

  1. // WeGraph.c: an adjacency matrix implementation of a weighted graph
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include "WeGraph.h"
  5.  
  6. struct graphRep {
  7. int nV; // #vertices
  8. int nE; // #edges
  9. Weight **edges; // matrix of weights
  10. };
  11.  
  12. Graph newGraph(int numVertices) {
  13. Graph g = NULL;
  14. if (numVertices < 0) {
  15. fprintf(stderr, "newgraph: invalid number of vertices\n");
  16. }
  17. else {
  18. g = malloc(sizeof(struct graphRep));
  19. if (g == NULL) {
  20. fprintf(stderr, "newGraph: out of memory\n");
  21. exit(1);
  22. }
  23. g->edges = malloc(numVertices * sizeof(int *));
  24. if (g->edges == NULL) {
  25. fprintf(stderr, "newGraph: out of memory\n");
  26. exit(1);
  27. }
  28. int v;
  29. for (v = 0; v < numVertices; v++) {
  30. g->edges[v] = malloc(numVertices * sizeof(int));
  31. if (g->edges[v] == NULL) {
  32. fprintf(stderr, "newGraph: out of memory\n");
  33. exit(1);
  34. }
  35. int j;
  36. for (j = 0; j < numVertices; j++) {
  37. g->edges[v][j] = NOWEIGHT;
  38. }
  39. }
  40. g->nV = numVertices;
  41. g->nE = 0;
  42. }
  43. return g;
  44. }
  45.  
  46. void freeGraph(Graph g) {
  47. if (g != NULL) {
  48. int i;
  49. for (i = 0; i < g->nV; i++) {
  50. free(g->edges[i]); // free the mallocs for each row ...
  51. }
  52. free(g->edges); // now the malloc for the edges array ...
  53. free(g); // now the malloc for the graph rep
  54. }
  55. return;
  56. }
  57.  
  58. static int validV(Graph g, Vertex v) { // checks if v is in graph
  59. return (v >= 0 && v < g->nV);
  60. }
  61.  
  62. Edge newEdge(Vertex v, Vertex w, Weight x) { // create an edge from v to w
  63. Edge e = {v, w, x};
  64. return e;
  65. }
  66.  
  67. void showEdge(Edge e) { // print an edge and its weight
  68. printf("%d-%d: %.2f", e.v, e.w, e.x);
  69. return;
  70. }
  71.  
  72. int isEdge(Edge e, Graph g) { // 0 if not found, else 1; also fill in wgt
  73. int found = 0;
  74. if (g != NULL) {
  75. if (g->edges[e.v][e.w] != NOWEIGHT) {
  76. found = 1;
  77. }
  78. }
  79. return found;
  80. }
  81.  
  82. Edge getEdge(Vertex v, Vertex w, Graph g) {
  83. Edge e = {0, 0, 0.0};
  84. if (validV(g, v) || validV(g, w)) {
  85. e.v = v;
  86. e.w = w;
  87. e.x = g->edges[v][w];
  88. }
  89. return e;
  90. }
  91.  
  92. int cmpEdge(Edge e1, Edge e2) { // comparison based on edge weight
  93. int retval = 0;
  94. if (e1.x < e2.x) {
  95. retval = -1;
  96. }
  97. else if (e1.x > e2.x) {
  98. retval = 1;
  99. }
  100. return retval;
  101. }
  102.  
  103. void insertEdge(Edge e, Graph g) { // insert an edge into a graph
  104. if (g == NULL) {
  105. fprintf(stderr, "insertEdge: graph not initialised\n");
  106. }
  107. else {
  108. if (!validV(g, e.v) || !validV(g, e.w)) {
  109. fprintf(stderr, "insertEdge: invalid vertices %d-%d\n", e.v, e.w);
  110. }
  111. else {
  112. if (!isEdge(e, g)) { // increment nE only if it is new
  113. g->nE++;
  114. }
  115. g->edges[e.v][e.w] = e.x;
  116. g->edges[e.w][e.v] = e.x;
  117. }
  118. }
  119. return;
  120. }
  121.  
  122. void removeEdge(Edge e, Graph g) { // remove an edge from a graph
  123. if (g == NULL) {
  124. fprintf(stderr, "removeEdge: graph not initialised\n");
  125. }
  126. else {
  127. if (!validV(g, e.v) || !validV(g, e.w)) {
  128. fprintf(stderr, "removeEdge: invalid vertices\n");
  129. }
  130. else {
  131. if (isEdge(e, g) == NOWEIGHT) { // is edge there?
  132. g->edges[e.v][e.w] = NOWEIGHT;
  133. g->edges[e.w][e.v] = NOWEIGHT;
  134. g->nE--;
  135. }
  136. }
  137. }
  138. return;
  139. }
  140.  
  141. Weight getWeight(Graph g, Vertex v1, Vertex v2) { // get Weight: NOWEIGHT if not existing
  142. Edge e = {v1, v2}; // not required, but for consistency
  143. Weight retval = 0.0;
  144.  
  145. if (g == NULL) {
  146. fprintf(stderr, "getWeight: graph not initialised\n");
  147. }
  148. else {
  149. if (!validV(g, e.v) || !validV(g, e.w)) {
  150. fprintf(stderr, "getWeight: invalid vertices\n");
  151. }
  152. else {
  153. retval = g->edges[e.v][e.w];
  154. }
  155. }
  156. return retval;
  157. }
  158.  
  159. void showGraph(Graph g) { // print a graph
  160. if (g == NULL) {
  161. printf("NULL graph\n");
  162. }
  163. else {
  164. printf("V=%d, E=%d\n", g->nV, g->nE);
  165. int i;
  166. for (i = 0; i < g->nV; i++) {
  167. int nshown = 0;
  168. int j;
  169. for (j = 0; j < g->nV; j++) {
  170. if (g->edges[i][j] != NOWEIGHT) {
  171. printf("%d %d:%.2f ", i, j, g->edges[i][j]);
  172. nshown++;
  173. }
  174. }
  175. if (nshown > 0) {
  176. printf("\n");
  177. }
  178. }
  179. }
  180. return;
  181. }

WeGraph.h

  1. // WeGraph.h: an interface for a weighted graph ADT
  2. #include <math.h>
  3.  
  4. typedef float Weight; // define a WEIGHT
  5. #define NOWEIGHT -1.0
  6. #define MAXWEIGHT INFINITY
  7.  
  8. typedef int Vertex; // define a VERTEX
  9. #define UNVISITED -1
  10. #define VISITED 1
  11.  
  12. typedef struct {
  13. Vertex v;
  14. Vertex w;
  15. Weight x;
  16. } Edge;
  17.  
  18. typedef struct graphRep *Graph; // define a GRAPH
  19.  
  20. Graph newGraph(int);
  21. void freeGraph(Graph);
  22. void showGraph(Graph);
  23.  
  24. void insertEdge(Edge, Graph);
  25. void removeEdge(Edge, Graph);
  26. void showEdge(Edge);
  27. int isEdge(Edge, Graph);
  28. Edge newEdge(Vertex, Vertex, Weight);
  29. Edge getEdge(Vertex, Vertex, Graph);
  30. int cmpEdge(Edge, Edge);
  31.  
  32. Weight getWeight(Graph, Vertex, Vertex);

【428】Dijkstra 算法的更多相关文章

  1. 求两点之间最短路径-Dijkstra算法

     Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.D ...

  2. Dijkstra算法优先队列实现与Bellman_Ford队列实现的理解

    /* Dijkstra算法用优先队列来实现,实现了每一条边最多遍历一次. 要知道,我们从队列头部找到的都是到 已经"建好树"的最短距离以及该节点编号, 并由该节点去更新 树根 到其 ...

  3. 关于dijkstra算法的一点理解

    最近在准备ccf,各种补算法,图的算法基本差不多看了一遍.今天看的是Dijkstra算法,这个算法有点难理解,如果不深入想的话想要搞明白还是不容易的.弄了一个晚自习,先看书大致明白了原理,就根据书上的 ...

  4. 最短路模板(Dijkstra & Dijkstra算法+堆优化 & bellman_ford & 单源最短路SPFA)

    关于几个的区别和联系:http://www.cnblogs.com/zswbky/p/5432353.html d.每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个(草儿家到 ...

  5. Dijkstra算法(二)之 C++详解

    本章是迪杰斯特拉算法的C++实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法图解 3. 迪杰斯特拉算法的代码说明 4. 迪杰斯特拉算法的源码 转载请注明出处:http://www.cnbl ...

  6. Dijkstra算法(一)之 C语言详解

    本章介绍迪杰斯特拉算法.和以往一样,本文会先对迪杰斯特拉算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 迪杰斯特拉算法介绍 2. 迪杰斯特拉算法 ...

  7. 最短路问题Dijkstra算法

    Dijkstra算法可以解决源点到任意点的最短距离并输出最短路径 准备: 建立一个距离数组d[ n ],记录每个点到源点的距离是多少 建立一个访问数组v[ n ],记录每个点是否被访问到 建立一个祖先 ...

  8. dijkstra算法求最短路

    艾兹格·W·迪科斯彻 (Edsger Wybe Dijkstra,1930年5月11日~2002年8月6日)荷兰人. 计算机科学家,毕业就职于荷兰Leiden大学,早年钻研物理及数学,而后转为计算学. ...

  9. 数据结构之Dijkstra算法

    基本思想 通过Dijkstra计算图G中的最短路径时,需要指定起点s(即从顶点s开始计算). 此外,引进两个集合S和U.S的作用是记录已求出最短路径的顶点(以及相应的最短路径长度),而U则是记录还未求 ...

  10. ACM: HDU 1869 六度分离-Dijkstra算法

    HDU 1869六度分离 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Descri ...

随机推荐

  1. gosched

    Go语言runtime.Gosched()函数浅析 这个函数的作用是让当前goroutine让出CPU,好让其它的goroutine获得执行的机会.同时,当前的goroutine也会在未来的某个时间点 ...

  2. 六.搭建基本的Web服务

    1.安装httpd软件包 ]# yum -y install httpd 2.重起httpd服务 ]# systemctl restart httpd ]# systemctl enable http ...

  3. IIS服务部署页面

    本周学习内容 1.看完了html和黑客达人迷剩下的3/5,总结黑客达人迷: 2.编写网站部署到本地IIS服务器,设置防火墙策略: 3.安装nmap,使用nmap扫描同组计算机: 4.使用SVN提交每日 ...

  4. #505. 「LibreOJ β Round」ZQC 的游戏

    题目描述 首先一定是让ZQC吃掉他能吃到的所有的球,这样才能尽可能的满足ZQC的质量是所有玩家中最大的. 在满足某一个玩家的质量不会超过ZQC的情况下,让这个玩家吃掉尽可能多的球,让其他玩家吃掉的尽可 ...

  5. 机器学习---用python实现朴素贝叶斯算法(Machine Learning Naive Bayes Algorithm Application)

    在<机器学习---朴素贝叶斯分类器(Machine Learning Naive Bayes Classifier)>一文中,我们介绍了朴素贝叶斯分类器的原理.现在,让我们来实践一下. 在 ...

  6. golang-笔记2

    结构体: 是一种数据 类型. type Person struct { —— 类型定义 (地位等价于 int byte bool string ....) 通常放在全局位置. name string ...

  7. ehcache 配置说明

  8. Maven+SSM整合ehcache

  9. 树——倍增LCA

    与正文无瓜的前言 身为一个高一才开始学的OIER,现在才开始恶补模板,感觉今年就要退役了. 不想刷题了滚过来写写博客<-------极端危险的思想. 引入 LCA(Lowest Common A ...

  10. 从一个表中往另外一个表中插入数据用到的SQL

    insert into jdjc_zzjcxm (zj,jcxmmc) select sys_guid(),zbmc from JDJC_WHJXXMMC;