关键路径:一个图中长度最长(路径上的各个活动持续时间之和)的路径,具体算法:
1.从顶点v0开始,假设ve(0)=0,然后按照拓扑有序求出其他各顶点i的最早开始时间ve(i),如果得到的拓扑序列中顶点数目小于图中的顶点数,则表示图中有环,算法结束,否则继续。
2.从结束顶点vn出发,假设vl(n-)=ve(n-1),然后按拓扑有序求出其他各顶点i的最晚发生时间vl(i)。
3.根据各顶点的最早开始时间ve(i)和最晚开始时间vl(i)依次求出每条弧的最早开始时间e(k)和最晚开始时间l(k),如果有e(k)=l(k),则为关键活动,关键活动组成的路径即为关键路径。
void CriticalPath(Graph *G)
{
int *etv, *ltv; //事件最早发生时间和最晚发生时间数组
int top; //用于Stack的指针
int *Stack; //用于存储拓扑结构序列的栈
int ete, lte; //声明事件最早发生时间和最晚发生时间的变量
TopoLogicalSort(G); //拓扑排序求事件的最早发生时间和拓扑序列Stack
ltv = (int*)malloc(sizeof(EdgeNode)*G->Numvertex);
for (int i = 0;i < G->NumVertex;++i) //初始化时间最晚发生时间
{
ltv[i] = etv[G->NumVertex - 1];
}
while (top != 0) //如果栈不为空
{
int gettop = Stack[top--]; //出栈
//处理下标为gettop的顶点所连接的顶点
for (EdgeNode*e = G->Vertex[gettop].FirstEdge;e;e = e->next)
{
int k = e->AdjVex;
if (ltv[k] - e->weight < ltv[gettop])
ltv[gettop] = ltv[k] - e->weight;
}
}
for (int i = 0;i < G->NumVertex;++i)
{
for (EdgeNode*e = G->Vertex[i].FirstEdge;e;e = e->next)
{
int k = e->AdjVex;
ete = etv[i]; //时间最早发生时间
lte = ltv[k] - e->weight; //时间最晚发生时间
if (ete == lte) //相等即在关键路径上
{
printf("<V%d->V%d:%d\n", G->Vertex[i].data, G->Vertex[k].data, e->weight);
}
}
}
}