关键路径
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一.实验名称:关键路径
二.实验目的:
1.熟悉图的存储结构
2.掌握求关键路径的算法
3.了解实际问题的求解效率与采用何种存储结构和算法有密切关系
三.程序
#include "stdio.h"
#include "malloc.h"
//-----图的邻接表存储结构-----
typedef struct ArcNode{ //弧结点
int adjvex; //该弧指向的顶点的序号
struct ArcNode *nextarc; //指向下一条弧的指针
int info; //该弧相关信息的指针
}ArcNode,*Arc;
typedef struct VNode{ //顶点
char data; //顶点信息
ArcNode *firstarc; //指向第一条依附该顶点的弧
}VNode,AdjList[20];
typedef struct{ //图
AdjList vertices; //存储图的顶点的数组
int vexnum,arcnum; //图的当前定点数和弧数
}ALGraph;
typedef struct{ //栈
int *base,*top; //栈底和栈顶指针
int stacksize; //栈的长度
}SqStack;
void CreateG(ALGraph &G,int m) //建顶点数为m的图
{int i,j,k,w; Arc p,q;
G.vexnum=m;G.arcnum=0; //对图进行初始化
for(i=0;i scanf("%c",&G.vertices[i].data); } for(i=1;i<=m;i++) //给各顶点连以其为尾的弧{printf("\nplease input VNode%d outarc:",i); scanf("%d",&j); //输入该顶点第一条弧指向的顶点在存储数组中的序号if(!j) G.vertices[i-1].firstarc=NULL; //j=0该顶点没有以其为尾的弧else { G.arcnum++; //弧数增加1 p=(Arc)malloc(sizeof(ArcNode)); //为该顶点开辟第一个弧结点p->adjvex=j-1; //该弧指向的顶点序号 G.vertices[i-1].firstarc=p; //把弧连到该顶点 for(;;) //建立该顶点的其他以其为尾的弧结点{scanf("%d",&k); if(!k) {p->nextarc=NULL;break;} else {G.arcnum++; q=(Arc)malloc(sizeof(ArcNode)); q->adjvex=k-1; p->nextarc=q; //前一条弧指向后一条弧 } } } }//所有弧结点建立完毕 for(i=1;i<=m;i++) //分别输入每个顶点以其为尾的弧的信息{printf("\nplease input arcs'information of VNode%d:",i); p=G.vertices[i-1].firstarc; while(p) {scanf("%d",&w); p->info=w; p=p->nextarc; } }printf(“\n”); } void FindInDegree(ALGraph G,int*indegree) //求图G各顶点的入度,存入数组indegree中,序号对应于顶点序号 {int i;Arc p; indegree=(int *)malloc(G.vexnum*sizeof(int)); for(i=0;i for(i=1;i<=G.vexnum;i++) {p=G.vertices[i-1].firstarc; //p指向弧结点 while(p) {indegree[p->adjvex]++; //通过弧结点储存的指向的顶点序号求各顶点入度p=p->nextarc; } } } void InitStack(SqStack &S) //构建一个空栈S {S.base=(int *)malloc(20*sizeof(int)); S.top=S.base; S.stacksize=20; int StackEmpty(SqStack S) //若栈S为空,则返回1,否则0 {if(S.base==S.top) return 1; else return 0; } int Pop(SqStack &S,int &e) //删除S的栈顶元素,并用e返回其值{if(S.top==S.base) return 0; e=*--S.top; return 1; } void Push(SqStack &S,int e) //插入元素e为新的栈顶元素{*S.top++=e;} int TopologicalOrder(ALGraph G,SqStack &T,int ve[ ]) //T为拓扑序列顶点栈,S为零入度顶点栈 //若G无回路,则用栈T返回G的一个拓扑序列,且函数值为1,否则为0 {int i,j,k,*indegree,count; Arc p; SqStack S; FindInDegree(G,indegree); //对各顶点求入度InitStack(S); //建零入度栈 for(i=0;i {if(!indegree[i]) Push(S,i);} InitStack(T); count=0; for(i=0;i ve[i]=0; while(!StackEmpty(S)) {Pop(S,j); Push (T,j); ++count; //j号顶点如T栈并计数for(p=G.vertices[j].firstarc; p; p=p->nextarc) k=p->adjvex; //对j号顶点的每个邻接点的入度减1 if(--indegree[k]==0) Push(S,k); //若入度为0,则如栈 if(ve[j]+p->info>ve[k]) ve[k]=ve[j]+p->info; } if(count else return 1; } int CriticalPath(ALGraph G) //G为有向网,输出G的各项关键活动{int j,k,dut,ee,el,vl[20],ve[20]; char tag; SqStack T;Arc p; if(!TopologicalOrder(G,T,ve)) return 0; for(j=0;j vl[j]=ve[j]; while(!StackEmpty(T)) //按拓扑排逆序求各顶点的v1值 for(Pop(T,j),p=G.vertices[j].firstarc;p;p=p->nextarc) {k=p->adjvex; dut=p->info; //活动持续时间dut if(vl[k]-dut