一、基础知识
二、代码要求
邻接矩阵、邻接表中任选一种作为图的存储结构,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
*/