1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <malloc.h>
  4.  
  5. #define MAXVEX 30 //最大顶点数
  6. #define MAXEDGE 30 //最大边数
  7. #define INFINITY 65535 //∞
  8.  
  9. //定义全局变量
  10. int *etv, *ltv;//事情最早发生和最迟发生指针数组
  11. int *stack2;//用于存储拓扑排序的栈
  12. int top2;//用于指向stack2栈指针
  13.  
  14. /* 邻接矩阵结构 */
  15. typedef struct
  16. {
  17. int vexs[MAXVEX];//顶点下标
  18. int arc[MAXVEX][MAXVEX];//矩阵(路径)
  19. int numVertexes, numEdges;//当前图中的顶点数和边数
  20. }MGraph;
  21.  
  22. /* 邻接表结构 */
  23. typedef struct EdgeNode //
  24. {//边表结点
  25. int adjvex;//顶点下标
  26. int weight;//路径
  27. struct EdgeNode *next;//指向想一个边表结点
  28. }EdgeNode;
  29.  
  30. typedef struct VertexNode
  31. {//顶点结点
  32. int in;//入度
  33. int data;//顶点信息
  34. EdgeNode *firstedge;//指向边表头指针
  35. }VertexNode, AdjList[MAXVEX];
  36.  
  37. typedef struct
  38. {
  39. AdjList adjList;//顶点向量
  40. int numVertexes, numEdges;//顶点数和边数
  41. }graphAdjList, *GraphAdjList;
  42.  
  43. void CreateMGraph(MGraph *G)
  44. {/* 构建图 */
  45. int i, j;
  46.  
  47. // printf("请输入顶点数和边数:\n");
  48. G->numVertexes = ;
  49. G->numEdges = ;
  50.  
  51. //初始化顶点下标
  52. for(i=; i<G->numVertexes; i++)
  53. G->vexs[i] = i;
  54.  
  55. //初始化矩阵
  56. for(i=; i<G->numVertexes; i++)
  57. for(j=; j<G->numVertexes; j++)
  58. if(i == j)
  59. G->arc[i][j] = ;
  60. else
  61. G->arc[i][j] = INFINITY;
  62.  
  63. //内置输入
  64. G->arc[][] = ;
  65. G->arc[][] = ;
  66. G->arc[][] = ;
  67. G->arc[][] = ;
  68. G->arc[][] = ;
  69. G->arc[][] = ;
  70. G->arc[][] = ;
  71. G->arc[][] = ;
  72. G->arc[][] = ;
  73. G->arc[][] = ;
  74. G->arc[][] = ;
  75. G->arc[][] = ;
  76. G->arc[][] = ;
  77.  
  78. return ;
  79. }
  80.  
  81. void CreateALGraph(MGraph G, GraphAdjList *GL)
  82. {/* 利用邻接矩阵,构建邻接表 */
  83. int i, j;
  84. EdgeNode *e;
  85.  
  86. *GL = (GraphAdjList)malloc(sizeof(graphAdjList));//*GL代表主函数的GL指向
  87. (*GL)->numVertexes = G.numVertexes;/* 读取信息 */
  88. (*GL)->numEdges = G.numEdges;
  89.  
  90. //初始化
  91. for(i=; i<G.numVertexes; i++)
  92. {
  93. (*GL)->adjList[i].in = ;
  94. (*GL)->adjList[i].data = G.vexs[i];//读取顶点下标
  95. (*GL)->adjList[i].firstedge = NULL;
  96. }
  97.  
  98. //构建邻接表
  99. for(i=; i<G.numVertexes; i++)
  100. for(j=; j<G.numVertexes; j++)
  101. if( != G.arc[i][j] && INFINITY > G.arc[i][j])
  102. {//若存在路径
  103. e = (EdgeNode *)malloc(sizeof(EdgeNode));//申请
  104. e->adjvex = j;//存顶点
  105. e->weight = G.arc[i][j];//存路径
  106. e->next = (*GL)->adjList[i].firstedge;//存表头指针
  107. (*GL)->adjList[i].firstedge = e;//头插
  108. (*GL)->adjList[j].in ++;//顶点入度+1
  109. }
  110. return ;
  111. }
  112.  
  113. void TopologicalSort(GraphAdjList GL)
  114. {/* 拓扑排序 */
  115. EdgeNode *e;
  116. int i, gettop, k;
  117. int top = ;//用于指向stack栈顶
  118. int count = ;//技术输出
  119. int *stack;//建栈存储入度位0的顶点
  120. stack = (int *)malloc(sizeof(int));
  121. for(i=; i<GL->numVertexes; i++)//把所有入度位0的顶点如stack栈中
  122. if( == GL->adjList[i].in)
  123. stack[++top] = i;
  124.  
  125. etv = (int *)malloc(sizeof(int) * GL->numVertexes);//最早发生etv指针申请空间
  126. for(i=; i<GL->numVertexes; i++)//初始化最早发生etv数组
  127. etv[i] = ;
  128.  
  129. stack2 = (int *)malloc(sizeof(int) * GL->numVertexes);//存储拓扑排序序列
  130. top2 = ;//用于指向stack2栈顶
  131. printf("Topological:\t");
  132. while( != top)
  133. {//若有顶点入度为0
  134. gettop = stack[top--];//出栈
  135. printf("%3d->", GL->adjList[gettop].data);//输出出栈的栈顶的顶点信息
  136. count ++;//输出记数
  137.  
  138. stack2[++top2] = gettop;//出栈元素赋给存储拓扑序列栈
  139.  
  140. for(e=GL->adjList[gettop].firstedge; e; e=e->next)
  141. {//出栈的栈顶元素若有邻接点
  142. k = e->adjvex;//邻接点-顶点下标
  143. if(! (--GL->adjList[k].in))//邻接点顶点下标-1(gettop已指向),是否入度位0?
  144. stack[++top] = k;//是则入stack的栈
  145.  
  146. /*出栈的最早发生时间值+出栈邻接表的路径 > 出栈邻接表顶点下标的最早发生时间值
  147. 就是v0-v1-v3和v0-v2-v3都是从起点到达汇点,3哪一个路径较远 */
  148. if((etv[gettop] + e->weight) > etv[k])
  149. etv[k] = etv[gettop] + e->weight;
  150. }
  151. }
  152. printf("\n");
  153.  
  154. if(count < GL->numVertexes)//若有环,则结束程序
  155. exit(-);
  156.  
  157. return ;
  158. }
  159.  
  160. void CriticalPath(GraphAdjList GL)
  161. {/* 关键路径 */
  162. EdgeNode *e;
  163. int i, gettop, k, j;
  164. int ete, lte;//最早发生和最迟发生的变量
  165.  
  166. TopologicalSort(GL);//调用拓扑排序函数
  167.  
  168. ltv = (int *)malloc(sizeof(int) * GL->numVertexes);//最迟发生指针边表指向申请空间
  169. for(i=; i<GL->numVertexes; i++)//初始化最迟发生数组
  170. ltv[i] = etv[GL->numVertexes - ];//起到汇最大值
  171.  
  172. //输出最早发生数组
  173. printf("etv:\t\t");
  174. for(i=; i<GL->numVertexes; i++)
  175. printf("%3d->", etv[i]);
  176. printf("\n");
  177.  
  178. while( != top2)
  179. {//存放拓扑排序数列
  180. gettop = stack2[top2--];
  181. for(e=GL->adjList[gettop].firstedge; e; e=e->next)
  182. {
  183. k = e->adjvex;
  184. if((ltv[k] - e->weight) < ltv[gettop])
  185. ltv[gettop] = ltv[k] - e->weight;
  186. /*最晚发生时间值(出stack2(存拓扑排序)栈元素的邻接点顶点下标) - 邻接路径 < 最晚发生数组【出栈元素0】
  187. 用拓扑排序的最长路径 - 邻接路径 < 最晚发生值[出栈元素]*/
  188. }
  189. }
  190.  
  191. printf("ltv:\t\t");//输出最晚值数组
  192. for(i=; i<GL->numVertexes; i++)
  193. printf("%3d->", ltv[i]);
  194. printf("\n");
  195.  
  196. for(j=; j<GL->numVertexes; j++)
  197. for(e=GL->adjList[j].firstedge; e; e=e->next)
  198. {
  199. k = e->adjvex;
  200. ete = etv[j];//最早发生时间
  201. lte = ltv[k] - e->weight;//最迟发生时间
  202.  
  203. if(ete == lte)//相等即在关键路径上
  204. printf("<v%d - v%d> length : %d \n", GL->adjList[j].data, GL->adjList[k].data, e->weight);
  205. }
  206.  
  207. return ;
  208. }
  209.  
  210. int main(void)
  211.  
  212. {
  213. MGraph G;
  214. GraphAdjList GL;
  215. system("title 关键路径");
  216. CreateMGraph(&G);
  217. CreateALGraph(G, &GL);
  218. CriticalPath(GL);
  219.  
  220. return ;
  221. }

关键路径(CriticalPath)算法的更多相关文章

  1. 关键路径——CriticalPath算法

    背景:本文是在小甲鱼数据结构教学视频中的代码的基础上,添加详细注释而完成的.该段代码并不完整,仅摘录了核心算法部分,结合自己的思考,谈谈理解. 关键路径: 即决定一项工程的完成时间的路径. 如下图所示 ...

  2. 算法与数据结构(八) AOV网的关键路径

    上篇博客我们介绍了AOV网的拓扑序列,请参考<数据结构(七) AOV网的拓扑排序(Swift面向对象版)>.拓扑序列中包括项目的每个结点,沿着拓扑序列将项目进行下去是肯定可以将项目完成的, ...

  3. 算法与数据结构(八) AOV网的关键路径(Swift版)

    上篇博客我们介绍了AOV网的拓扑序列,请参考<数据结构(七) AOV网的拓扑排序(Swift面向对象版)>.拓扑序列中包括项目的每个结点,沿着拓扑序列将项目进行下去是肯定可以将项目完成的, ...

  4. 图->有向无环图->求关键路径

    文字描述 与AOV-网相对应的是AOE-网(Activity on Edge)即边表示活动的网.AOE-网是一个带权的有向无环图.其中,顶点表示事件Event,弧表示活动,权表示活动持续的时间.通常, ...

  5. AOE网与关键路径简介

    前面我们说过的拓扑排序主要是为解决一个工程能否顺序进行的问题,但有时我们还需要解决工程完成需要的最短时间问题.如果我们要对一个流程图获得最短时间,就必须要分析它们的拓扑关系,并且找到当中最关键的流程, ...

  6. java数据结构_笔记(5)_图的算法

    图的算法 1 图的遍历图的遍历就是从图中某个顶点出发,按某种方法对图中所有顶点访问且仅访问一次.遍历算法是求解图的连通性问题.拓扑排序和求关键路径等算法的基础. 2 深度优先遍历从图中某个顶点V 出发 ...

  7. MindFusion 中节点关键路径的遍历

    工作中总能遇到 一些 奇葩的需求,提出这些奇葩需求的人,多半也是奇葩的人,要么不懂相关的计算机软件知识,要么就是瞎扯蛋,异想天开,然而这些奇葩的需求,我也总能碰到.言规正传,在一次项目中,使用了 Mi ...

  8. 数据结构(c语言版)代码

    第1章  绪论       文档中源码及测试数据存放目录:数据结构\▲课本算法实现\▲01 绪论  概述        第一章作为绪论,主要介绍了数据结构与算法中的一些基本概念和术语.对于这些概念术语 ...

  9. 返回数据方法DeaCacheCommand,由CRL自动实现

    越来越多的人学起了前端,或许部分的初衷仅是它简单易上手以及好找工作,毕竟几年前只会个html和css就能有工作,悄悄告诉泥萌,这也是博主一年前的初衷 还好numpy, scikit-learn都提供了 ...

随机推荐

  1. WPF/ArcGIS Engine三维开发和EVC3/4升级到VS项目建议(转)

    系统环境:Windows 7 专业版,Visual Studio 2010,ArcGIS Engine 9.3 1.创建项目 创建一个WPF的项目,必须选择.Net framework 3.5(AE9 ...

  2. Linux dirname、basename(转)

    首先使用 --help 参数查看一下.basename命令参数很少,很容易掌握. $ basename --help 用法示例: $ basename /usr/bin/sort       输出&q ...

  3. bzoj1664 [Usaco2006 Open]County Fair Events 参加节日庆祝

    Description Farmer John has returned to the County Fair so he can attend the special events (concert ...

  4. sizeof与类,继承,virtual的种种(整理)

    对虚继承层次的对象的内存布局,在不同编译器实现有所区别. 首先,说说GCC的编译器. 它实现比较简单,不管是否虚继承,GCC都是将虚表指针在整个继承关系中共享的,不共享的是指向虚基类的指针. clas ...

  5. HDU1232 畅通工程 (并查集模板题)

    畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  6. 修改MySQL 5.5的max_allowed_packet属性的方法

    今天在部署一个实验系统的时候,报出下面这个错: Your 'max_allowed_packet' variable is set to less than 16777216 Byte (16MB). ...

  7. ng-cli

    angluar2 cli 是一个比较好的工具 .解决 Angular 2 环境设置是一大入门门槛,有22%的人说环境设置太过复杂.Angular CLI的诞生,正是为了解决这个问题. 1. 基本介绍 ...

  8. Funny Sheep(思维)

    Problem 1606 - Funny Sheep Time Limit: 1000MS   Memory Limit: 65536KB    Total Submit: 612  Accepted ...

  9. 水池数目(DFS)

    水池数目 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池,假设有一张我们学校的某处的地图,这个地 ...

  10. Unity 4.6 uGUI的点击事件

    因为Unity 4.6刚刚发布,自带的uGUI功能的相关资料还不是很完善,今天刚装的Unity 4.6,想看一下uGUI是否好用,那么开始就今天的学习吧啊! 1,新建一个空的工程.