关键路径的算法实现(C++)

对于关键路径算法实现了一下,下面附上代码 相比于原博文 ,做出了一些调整.
添加链接描述

#include <stdio.h>  
#include <stdlib.h>  
#define MaxVerNum 20  
   
int visited[MaxVerNum];//访问标志  
   
typedef char VertexType;  
   
typedef struct ArcNode  
{  
       int adjvex;                                         //该弧指向的顶点位置  
       struct ArcNode * nextarc;          //指向下一个表结点  
       int info;                                      //权值信息  
}ArcNode;                                              //边结点类型  
   
typedef struct VNode  
{  
       VertexType data;  //顶点的数据域
       int indegree;  //该顶点的度
       ArcNode * firstarc;  //该顶点的的第一条邻接边
}VNode, Adjlist[MaxVerNum];  
   
typedef struct  
{  
       Adjlist vertices;            //邻接表  
       int vernum, arcnum;             //顶点数和弧数  
}ALGraph;  
   
//查找符合的数据在数组中的下标  
//返回该顶点在顶点数组中的位置
int LocateVer(ALGraph G, char u)  
{  
       int i;  
       for(i = 0; i < G.vernum; i++)  
       {  
		//就是通过比较数据域是否相等
              if(u == G.vertices[i].data)  
                     return i;  
       }  
       if(i == G.vernum)  
       {  
              printf("Error u!\n");  
              exit(1);  
       }  
       return 0;  
}  
   
//常见图的邻接矩阵  
void CreateALGraph(ALGraph &G)  
{  
       int i, j, k, w;  
       char v1, v2;  
       ArcNode * p;  
       printf("输入顶点数和弧数: ");  
       scanf("%d %d", &G.vernum, &G.arcnum); //vernum是值顶点数 
       printf("请输入顶点!\n");  
       for(i = 0; i < G.vernum; i++)  
       {  
	//挨个输入顶点的信息  输入这个顶点的入度  数据信息  以及第一条边的指针
              printf("请输入第 %d 个顶点: \n", i);  
              fflush(stdin);  
              scanf("%c", &G.vertices[i].data); 
		//初始化的时候  将其的入度设置位0,第一条指针设置为空 
              G.vertices[i].firstarc = NULL;  
              G.vertices[i].indegree = 0;  
       }  
   
       for(k = 0; k < G.arcnum; k++)  
       {  
              printf("请输入弧的顶点和相应权值(v1, v2, w): \n");  
              //清空输入缓冲区  
              fflush(stdin);  
		//输入这条弧对对应顶点  以及这条弧对应的权值
              scanf("%c %c %d", &v1, &v2, &w); 
		//返回这两个顶点在顶点数组中的位置
              i = LocateVer(G, v1);  
              j = LocateVer(G, v2);  
		//给邻接表指针分配空间
              p = (ArcNode *)malloc(sizeof(ArcNode));  
              p->adjvex = j;  //赋值给p->adjvex指向的顶点域
              p->info = w;  //边表结点的权值
		//这里采用的是头插法 将边插入的边表中去
              p->nextarc = G.vertices[i].firstarc;//它的nextarc指针域指向i结点的firstarc指针域  
              G.vertices[i].firstarc = p;//将点i的第一条指针指向  
              G.vertices[j].indegree++;                   //vi->vj, vj入度加1  
       }  
       return;  
}  
   
//求图的关键路径函数  
void CriticalPath(ALGraph G)  
{  
       int i, k, e, l;  
       int * Ve, * Vl;  
       ArcNode * p;  
   
       //*****************************************  
       //以下是求时间最早发生时间  
       //*****************************************  
   
       Ve = new int [G.vernum];  //最早发生时间
       Vl = new int [G.vernum];  //最迟发生时间
   
       for(i = 0; i < G.vernum; i++)              //前推  
              Ve[i] = 0;  //先将最早开始时间全部设置为0
   
       for(i = 0; i < G.vernum; i++)  
       {  
              ArcNode * p = G.vertices[i].firstarc;  
              while(p != NULL)  
              {  
                     k = p->adjvex;  
		//找到最大的路径的权值赋值给Ve[K]
                     if(Ve[i] + p->info > Ve[k])  
                            Ve[k] = Ve[i]+p->info;  
                     p = p->nextarc;  
              }  
       }  
       //*****************************************  
       //以下是求最迟发生时间  
       //*****************************************  
       for(i = 0; i < G.vernum; i++)  
              Vl[i] = Ve[G.vernum-1];//先将数组初始化位最长路径  就是上面算出来的总路径  
       for(i = G.vernum-2; i >= 0; i--)                 //后推   
       {  //使用从后往前移动的方式  这里i=G.vernum-2开始  是因为G.vernum这个位置位不需要再考虑了  它就是最大值
              p = G.vertices[i].firstarc;  
              while(p != NULL)  
              {  
                     k = p->adjvex;  
			//此时通过比较把较小的值赋值给vl[i]  最为最迟开始时间
                     if(Vl[k] - p->info < Vl[i])  
                            Vl[i] = Vl[k] - p->info;  
                     p = p->nextarc;  //遍历找到最小的
              }  
       }  
       //******************************************  
       for(i = 0; i < G.vernum; i++)  
       {  
              p = G.vertices[i].firstarc;  
              while(p != NULL)  
              {  //
                     k = p->adjvex;  
                     e = Ve[i];              //最早开始时间为时间vi的最早发生时间  
                     l = Vl[k] - p->info;             //最迟开始时间  这里用到的减法 表示的是活动的最迟开始时间
			//此活动再晚也需要在头顶点是事件发生之前完成  
                   //如果最早时间等于最晚时间 则证明这是关键路径
                     char tag = (e == l) ? '*' : ' '; //关键活动  
                     printf("(%c, %c), e = %2d, l = %2d, %c\n", G.vertices[i].data, G.vertices[k].data, e, l, tag);  
                     p = p->nextarc;  
              }  
       }  
       delete [] Ve;  
       delete [] Vl;  
}  
   
int  main()  
{  
       ALGraph G;  
       printf("以下是查找图的关键路径的程序。\n");  
       CreateALGraph(G);  
       CriticalPath(G);  
	return 0;
}  


  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值