关键路径算法 c语言,关键路径算法C++实现代码

下面是编程之家 jb51.cc 通过网络收集整理的代码片段。

编程之家小编现在分享给大家,也给大家做个参考。

#include

#include

#include

#include

#include

#define MAX_VERTEX_NUM 30 //图的最大顶点数

#define MAX 30 //栈的最大容量

#define INFINITY 30000; //定义最大的最迟发生时间

enum BOOL {False,True};

typedef struct ArcNode

{

int adjvex; //该弧所指向的顶点的位置

int weight; //该弧所代表的活动的持续时间

struct ArcNode *nextarc; //指向下一条弧的指针

} ArcNode; //弧结点

typedef struct

{

int indegree[MAX_VERTEX_NUM]; //存放各顶点的入度

ArcNode* AdjList[MAX_VERTEX_NUM]; //指向第一条依附该顶点的弧的指针

int vexnum,arcnum; //图的当前顶点和弧数

} Graph;

typedef struct //定义堆栈结构

{

int elem[MAX]; //栈区

int top; //栈顶指针

} Stack;

int ve[MAX_VERTEX_NUM]; //全局变量,存放各顶点的最早发生时间

void CreateGraph ( Graph & ); //生成图的邻接表

BOOL CriticalPath ( Graph ); //求图的关键路径

BOOL TopologicalSort ( Graph,Stack &T ); //进行拓扑排序

void FindInDegree ( Graph& ); //求图各顶点的入度

void Initial ( Stack & ); //初始化一个堆栈

BOOL Push ( Stack &,int ); //将一个元素入栈

BOOL Pop ( Stack&,int & ); //将一个元素出栈

BOOL Gettop ( Stack,int& ); //得到栈顶元素

BOOL StackEmpty ( Stack ); //判断堆栈是否为空

void main()

{

Graph G; //采用邻接表结构的图

char j='y';

BOOL temp;

textbackground ( 3 ); //设定屏幕颜色

textcolor ( 15 );

clrscr();

//------------------程序解说----------------------------

printf ( "本程序将演示构造图的关键路径.\n" );

printf ( "首先输入图的顶点数和弧数.\n格式:顶点数,弧数;例如:6,8\n" );

printf ( "接着输入各弧(弧尾,弧头)和权值.\n格式:弧尾,弧头,权值;例如:\n1,2,3\n1,3,2\n" );

printf ( "2,5,3\n5,6,1\n2,4,2\n4,2\n3,4\n3,3\n" );

printf ( "程序将会构造该图并找出其关键路径.\n" );

printf ( "关键路径:\n1->3 2\n3->4 4\n4->5 2\n" );

//------------------------------------------------------

while ( j!='N'&&j!='n' )

{

CreateGraph ( G ); //生成邻接表结构的图

temp=CriticalPath ( G ); //寻找G的关键路径

if ( temp==False ) printf ( "该图有回路!\n" );

//若返回为False,表明该图存在有环路

else printf ( "该图没有回路!\n" );

printf ( "关键路径演示完毕,继续进行吗?(Y/N)" );

scanf ( " %c",&j );

}

}

BOOL CriticalPath ( Graph G )

{//G为有向网,输出G的各项关键活动

int j,dut,k,ee,el;

int vl[MAX_VERTEX_NUM]; //存放各顶点的最迟发生时间

Stack T; //堆栈T存放拓扑排序的顶点序列

ArcNode*p;

Initial ( T ); //初始化堆栈T

if ( !TopologicalSort ( G,T ) ) return False;

//利用拓扑排序求出各顶点的最早发生时间,并用T返回拓扑序列,

//若返回False,表明该网有回路

printf ( "Critical Path:\n" );

Gettop ( T,k ); //k取得拓扑序列的最后一个顶点,即该网的汇点

vl[k]=ve[k]; //汇点的vl=ve

for ( j=1; j<=G.vexnum; j++ ) if ( j!=k ) vl[j]=INFINITY; //将其他的顶点的vl置为IFINITY

while ( !StackEmpty ( T ) ) //按拓扑逆序求各顶点的vl值

{

Pop ( T,j );

for ( p=G.AdjList[j]; p; p=p->nextarc )

{

k=p->adjvex;

dut=p->weight;

if ( vl[k]-dut

//vl的求法:vl(i)=Min{vl(j)-dut()} ∈S,i=n-2,...0

}

}

for ( j=1; j<=G.vexnum; j++ ) //求每条弧的最早开始时间ee和最迟开始时间el

for ( p=G.AdjList[j]; p; p=p->nextarc )

{

k=p->adjvex;

dut=p->weight;

ee=ve[j];

el=vl[k]-dut;

if ( ee==el ) printf ( "%d->%d%5d\n",j,dut ); //若ee=el,则该弧为关键活动

}

return True;

}

void CreateGraph ( Graph &G )

{//构造邻接表结构的图G

int i;

int start,end,arcweight;

ArcNode *s;

printf ( "请输入顶点数和弧数(顶点数,弧数):" );

scanf ( "%d,%d",&G.vexnum,&G.arcnum ); //输入图的顶点数和弧数

for ( i=1; i<=G.vexnum; i++ ) G.AdjList[i]=NULL; //初始化指针数组

printf ( "请输入各弧和权值,格式:弧尾,弧头,权值\n" );

for ( i=1; i<=G.arcnum; i++ )

{

scanf ( "%d,%d,&start,&end,&arcweight );

//输入弧的起点和终点即该弧所代表的活动的持续时间

s= ( ArcNode * ) malloc ( sizeof ( ArcNode ) ); //生成一个弧结点

s->nextarc=G.AdjList[start]; //插入到邻接表中

s->adjvex=end;

s->weight=arcweight;

G.AdjList[start]=s;

}

}

BOOL TopologicalSort ( Graph G,Stack &T )

{//有向网G采用邻接表存储结构,求各顶点事件的最早发生时间ve,

//T为拓扑序列顶点栈,S为零入度顶点栈。

//若G无回路,则用栈返回G的一个拓扑序列,且函数返回True,否则返回False

int i,k;

int count; //计数器

ArcNode* p;

Stack S;

FindInDegree ( G ); //求出图中各顶点的入度

Initial ( S ); //堆栈初始化,存放入度为零的顶点

for ( i=1; i<=G.vexnum; i++ )

if ( !G.indegree[i] ) Push ( S,i ); //入度为零的顶点入栈

count=0; //对输出顶点记数

for ( i=1; i<=G.vexnum; i++ )

ve[i]=0; //ve初始化

while ( !StackEmpty ( S ) )

{

Pop ( S,i ); //i号顶点出S栈并入T栈,count记数

Push ( T,i );

count++;

for ( p=G.AdjList[i]; p; p=p->nextarc )

{

k=p->adjvex; //对i号顶点的每个邻接顶点的入度减一

if ( ! ( --G.indegree[k] ) ) Push ( S,k ); //若入度为零,入栈

if ( ( ve[i]+p->weight ) >ve[k] ) ve[k]=ve[i]+p->weight;

//修改k号顶点的最迟发生时间

//ve的求法:ve(j)=Max{ve(i)+dut(

}

}

if ( count

else return True;

}

void FindInDegree ( Graph &G )

{//求出图G的各顶点的入度,存放在G.indegree[1..G.vexnum]中

int i;

ArcNode* p;

for ( i=1; i<=G.vexnum; i++ )

G.indegree[i]=0;

for ( i=1; i<=G.vexnum; i++ )

{

for ( p=G.AdjList[i]; p; p=p->nextarc )

G.indegree[p->adjvex]++; //弧头顶点的入度加一

}

}

void Initial ( Stack &S )

{

S.top=-1; //栈顶指针初始化为-1

}

BOOL Push ( Stack &S,int ch )

{//将元素ch入栈,成功返回True,失败返回False

if ( S.top>=MAX-1 ) return False;//判断是否栈满

else

{

S.top++; //栈顶指针top加一

S.elem[S.top]=ch; //入栈

return True;

}

}

BOOL Pop ( Stack &S,int &ch )

{//将栈顶元素出栈,成功返回True,并用ch返回该元素值,失败返回False

if ( S.top<=-1 ) return False;//判断是否栈空

else

{

S.top--; //栈顶指针减一

ch=S.elem[S.top+1];

return True;

}

}

BOOL Gettop ( Stack S,int &ch )

{//取得栈顶元素,成功返回True,并用ch返回该元素值,失败返回False

if ( S.top<=-1 )

return False;

else

{

ch=S.elem[S.top];//显示栈顶元素

return True;

}

}

BOOL StackEmpty ( Stack S )

{//判断堆栈是否已空,若空返回True,不空返回False

if ( S.top<=-1 ) return True;

else return False;

}

以上是编程之家(jb51.cc)为你收集整理的全部代码内容,希望文章能够帮你解决所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

总结

以上是编程之家为你收集整理的关键路径算法C++实现代码全部内容,希望文章能够帮你解决关键路径算法C++实现代码所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

小编个人微信号 jb51ccc

喜欢与人分享编程技术与工作经验,欢迎加入编程之家官方交流群!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值