数据结构总结15——图6——关键路径(AOE网关键路径算法) by DexterYan

一、基础知识

二、代码要求

邻接矩阵、邻接表中任选一种作为图的存储结构,AOE网关键路径算法,实现从AOE网源点到汇点的关键路径(2学时)

三、算法思路分析

四、算法反思

五、代码实现

#include<stdio.h>
#include<stdlib.h>
#define MaxVertexNum 100
typedef char VertexType;
typedef int EdgeType;

/*图的邻接表存储结构*/
typedef struct node//边表结点 
{
	int adjvex;					//邻接点域 
	struct node *next;			//指向下一个邻接点的指针域
	int info;	//若要表示边上的权值信息,则应增加一个数据域info 
}EdgeNode;
typedef struct vnode//表头结点 
{
	VertexType vertex;			//顶点域 
	EdgeNode *firstedge;		//边表头指针 
}VertexNode;
typedef struct
{
	VertexNode adjlist[MaxVertexNum];//邻接表 
	int n,e;						//顶点数和边数 
}ALGraph;//以邻接表方式存储的图类型 

int visited[MaxVertexNum];

void CreateALGraph(ALGraph *G)//有向图的邻接表存储的算法 
{
	int i, j, k, weight;
	EdgeNode *s;
	printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");
	scanf("%d,%d",&(G->n),&(G->e));		//读入顶点数和边数
//	printf("%d,%d",(G->n),(G->e));
	printf("请输入顶点信息(输入格式为:<回车>顶点号):\n");
	for(i=0; i<G->n; i++)
	{
		scanf("\n%c",&(G->adjlist[i].vertex));//读入顶点信息 
		G->adjlist[i].firstedge=NULL;//定点的边表头指针设为空 
	}
	printf("请输入边的信息(输入格式为:i,j,weight):\n");
	for(k=0; k<G->e; k++)//建立边表 
	{
		scanf("%d,%d,%d",&i,&j,&weight);//读入边<Vi,Vj>的顶点对应序号 
		s=(EdgeNode *)malloc(sizeof(EdgeNode));//生成新表边结点s 
		s->adjvex=j;//邻结点序号为j 
		s->info=weight;
		s->next=G->adjlist[i].firstedge;//将新表边结点s插入到顶点为Vi的边表头部,在录入的时候,只要i没改变,也就是起始顶点没改变就是在一行的 
		G->adjlist[i].firstedge=s;
	}
}

void CriticalPath(ALGraph *G)
{
	int i,j,k,e,l;
	int ve[MaxVertexNum],vl[MaxVertexNum];//建立ve,vl数组 
	EdgeNode *p;
	for(i=0; i<G->n; i++)					//初始化ve数组 
		ve[i]=0;
	for(i=0; i<G->n; i++)					//按拓扑有序求其余各顶点的最早发生时间 
	{
		p=G->adjlist[i].firstedge;
		while(p!=NULL)
		{
			k=p->adjvex;
			if(ve[i]+p->info>ve[k])
				ve[k]=ve[i]+p->info;
			p=p->next;
		}
	}
	for(i=0; i<G->n; i++)			//初始化vl数组 
		vl[i]=ve[G->n-1];
	for(i=G->n-2; i; i--)			//按逆拓扑有序求其余各顶点的最迟发生时间vl[i] 
	{
		p=G->adjlist[i].firstedge;
		while(p!=NULL)
		{
			k=p->adjvex;
			if(vl[k]-p->info<vl[i])
				vl[i]=vl[k]-p->info;
			p=p->next;
		}
	}
	for(i=0; i<G->n; i++)		//根据各顶点的ve和vl值,求出每条边上活动的开始时间e和最迟开始时间l 
	{
		p=G->adjlist[i].firstedge;//若某条边满足e==l 
		while(p!=NULL)//则这条边上的活动为关键活动 
		{
			k=p->adjvex;
			e=ve[i];
			l=vl[k]-p->info;
			if(e==l)
				printf("(%c,%c),e=%d,l=%d\n",G->adjlist[i].vertex,G->adjlist[k].vertex,e,l);
			p=p->next;
		}
	}
}

int main()
{
	ALGraph x;
	CreateALGraph(&x);
	CriticalPath(&x);
	return 0;
}

/*有错误,从读入顶点数和边数错了。 
void CreateALGraph(ALGraph *G)//有向图的邻接表存储的算法 
{
	int i, j, k, weight;
	EdgeNode *s;
	printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");
	scanf("%d,%d",&(G->n),&(G->e));		//读入顶点数和边数
	printf("%d,%d",(G->n),(G->e));
	printf("请输入顶点信息(输入格式为:<回车>顶点号):\n");
	for(i=0; i<G->n; i++)
	{
		scanf("\n%c",&(G->adjlist[i].vertex));//读入顶点信息 
		G->adjlist[i].firstedge=NULL;//定点的边表头指针设为空 
	}
	printf("请输入边的信息(输入格式为:i,j,weight):\n");
	for(k=0; k<G->e; k++)//建立边表 
	{
		scanf("%d,%d,%d",&i,&j,&weight);//读入边<Vi,Vj>的顶点对应序号 
		s=(EdgeNode *)malloc(sizeof(EdgeNode));//生成新表边结点s 
		s->adjvex=j;//邻结点序号为j 
		s->info=weight;
		s->next=G->adjlist[i].firstedge;//将新表边结点s插入到顶点为Vi的边表头部,在录入的时候,只要i没改变,也就是起始顶点没改变就是在一行的 
		G->adjlist[i].firstedge=s;
	}
}
错误原因:这个函数没错,具体错误见10数据结构6-1深度脑残bug2 
*/  

猜你喜欢

转载自blog.csdn.net/qq_41259302/article/details/94436876