这一篇来实现下关键路径~
例:求图中所示的AOE网络的关键路径并输出。
数据输入格式:首先输入顶点个数n和边数m,然后每行输入每条边<u, v>,表示从顶点u到顶点v的一条有向边。
Code如下:
#include<iostream>
using namespace std;
#define MAXN 100 //顶点个数最大值
#define MAXM 200 //边数的最大值
struct ArcNode
{
int to, dur, no; //边的另一个顶点、持续时间、活动序号
ArcNode *next;
};
int n, m; //顶点个数、边数
ArcNode *List1[MAXN]; //每个顶点的边链表表头指针(出边表)
ArcNode *List2[MAXM]; //每个顶点的边链表表头指针(入边表)
int count1[MAXN]; //各顶点的入度
int count2[MAXM]; //各顶点的出度
int Ee[MAXN]; //各事件的最早可能开始时间
int El[MAXN]; //各事件的最迟允许开始时间
int e[MAXM]; //各活动的最早可能开始时间
int L[MAXM]; //各活动的最迟允许开始时间
void CriticalPath() //求关键路径
{
//拓扑排序求Ee
int i, j, k;
int top1 = -1;
ArcNode *temp1;
memset(Ee, 0, sizeof(Ee));
for(i = 0; i < n; i++)
if(count1[i] == 0) { count1[i] = top1; top1 = i; }
for(i = 0; i < n; i++)
{
if(top1 == -1) { printf("Network has a cycle!\n"); return; }
else
{
j = top1; top1 = count1[top1];
temp1 = List1[j];
while(temp1 != NULL)
{
k = temp1->to;
if(--count1[k] == 0) { count1[k] = top1; top1 = k; }
if(Ee[j]+temp1->dur > Ee[k]) Ee[k] = Ee[j] + temp1->dur;//有向边<j, k>
temp1 = temp1->next;
}
}
}
//逆拓扑排序求El
int top2 = -1;
ArcNode *temp2;
for(i = 0; i < n; i++)
{
El[i] = Ee[n-1];
if(count2[i] == 0) { count2[i] = top2; top2 = i; }
}
for(i = 0; i < n; i++)
{
j = top2; top2 = count2[top2];
temp2 = List2[j];
while(temp2 != NULL)
{
k = temp2->to;
if(--count2[k] == 0) { count2[k] = top2; top2 = k; }
if(El[j]-temp2->dur < El[k]) El[k] = El[j] - temp2->dur;//有向边<k, j>
temp2 = temp2->next;
}
}
//求各活动的e[k]和L[k]
memset(e, 0, sizeof(e)); memset(L, 0, sizeof(L));
printf("The Critical activities are:\n");
for(i = 0; i < n; i++)
{
temp1 = List1[i];
while(temp1 != NULL)
{
j = temp1->to; k = temp1->no; //有向边<i, j>
e[k] = Ee[i]; L[k] = El[j] - temp1->dur;
if(e[k] == L[k]) printf("a%d : %d->%d\n", k, i, j);
temp1 = temp1->next;
}
}
}
int main()
{
int i, u, v, w; //循环变量、边的起点和终点
scanf("%d%d", &n, &m); //读入顶点个数和边数
memset(List1, 0, sizeof(List1)); memset(List2, 0, sizeof(List2));
memset(count1, 0, sizeof(count1)); memset(count2, 0, sizeof(count2));
ArcNode *temp1, *temp2;
for(i = 0; i < m; i++)
{
scanf("%d%d%d", &u, &v, &w); //读入边的起点和终点
count1[v]++;
temp1 = new ArcNode; //构造邻接表
temp1->to = v; temp1->dur = w;
temp1->no = i + 1; temp1->next = NULL;
if(List1[u] == NULL) List1[u] = temp1;
else { temp1->next = List1[u]; List1[u] = temp1; }
count2[u]++;
temp2 = new ArcNode; //构造逆邻接表
temp2->to = u; temp2->dur = w;
temp2->no = i + 1; temp2->next = NULL;
if(List2[v] == NULL) List2[v] = temp2;
else { temp2->next = List2[v]; List2[v] = temp2; }
}
CriticalPath();
for(i = 0; i < n; i++) //释放边链表上各边结点所占用的存储空间
{
temp1 = List1[i]; temp2 = List2[i];
while(temp1 != NULL) { List1[i] = temp1->next; delete temp1; temp1 = List1[i]; }
while(temp2 != NULL) { List2[i] = temp2->next; delete temp2; temp2 = List2[i]; }
}
return 0;
}
运行结果:
Ps:未完待续~
AOE网络与关键路径(二)——实现,布布扣,bubuko.com
原文:http://blog.csdn.net/zenail501129/article/details/23085529