关键路径

//图论算法理论,实现及应用
#include <stdio.h>
#include<string.h>
#define MAXN 100 //顶点个数最大值
#define MAXM 200//边数最大值
struct ArcNode 
{
	int to, dur, no;//边的另一顶点,持续时间,活动序号
	ArcNode *next;
};
int n, m;//顶点数,边数
ArcNode *List1[MAXN];//出边表
ArcNode *List2[MAXN];//入边表
int count1[MAXN];//入度
int count2[MAXN];//出度
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;
				temp1 = temp1->next;
			}


		}
	}
	//逆拓扑排序
	int top2 = -1;
	ArcNode *temp2;
	for (i = 0; i <= n; i++)
	{
		El[i] = Ee[n - 1];//初始化El
		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[k] > El[j] - temp2->dur)
				El[k] = El[j] - temp2->dur;
			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;
			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);//读入顶点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(List1[i]!=NULL)
			{
				List1[i] = temp1->next;
				delete temp1;
				temp1 = List1[i];
			}
			while (List2[i] != NULL)
			{
				List2[i] = temp2->next;
				delete temp2;
				temp2 = List2[i];
			}
		}
	return 0;
}


结果:



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值