您的位置:首页 > 其它

AOE-网--关键路径

2017-01-17 00:00 337 查看
#include <stdio.h>

#include <stdlib.h>

#include <string.h>

typedef struct ArcNode

{
int adjvex; //弧指向的顶点

int dutt; //权值

struct ArcNode * nextarc;

} ArcNode;

typedef struct VNode

{
int in; //顶点入度

int out; //顶点出度

int ve; //事件最早发生时间

int vl; //事件最迟发生时间

ArcNode * firstarc;

} VNode;

int VexNum;

int ArcNum;

void CreatGraph(VNode * Graph)

{
int i,j;

int startNode,endNode,dutt;

ArcNode * p;

//初始化顶点表数组

for ( i = 0; i < VexNum; i++)

{
Graph[i].in = 0;

Graph[i].out= 0;

Graph[i].firstarc = NULL;
}

printf("输入图中活动的起始点,终点,及权值:\n");

for (j = 0; j < ArcNum; j++)

{

scanf("%d,%d,%d",&startNode,&endNode,&dutt);

p = (ArcNode *)malloc(sizeof(ArcNode));

p->adjvex = endNode;

p->dutt = dutt;

Graph[startNode].out++;

Graph[endNode].in++;

p->nextarc = Graph[startNode].firstarc;

Graph[startNode].firstarc = p;

}

}

int TopologicalOrder(VNode * Graph )

{

int * Topo_Stack = (int *)malloc((VexNum+1)*sizeof(int)); //初始化拓扑有序栈

int * top = Topo_Stack , * flag = Topo_Stack;

ArcNode * p ;

int i,topo_num=0,k,tmp_out=0,max_ve=0;

for (i = 0; i < VexNum; i++)

{

Graph[i].ve = 0;

if(Graph[i].in == 0){

* top ++ = i;

topo_num++;

}

if(Graph[i].out == 0)

tmp_out ++;

}

if(topo_num > 1 || tmp_out > 1 ){

printf("源点数或汇点数大于1\n");

return 1;

}

// printf("%d\n",* -- top );exit(0);

while(flag != top){

i = * flag ++; //先从栈底取值,再自增

// printf("%d\n", i);

for (p = Graph[i].firstarc; p ; p = p->nextarc)

{

k = p->adjvex;

if(--Graph[k].in == 0)

{

* top ++ = k; //若入度减为0,k顶点入栈

topo_num++;

}

// printf("%d.....\n", topo_num);

if(Graph[i].ve + p->dutt > Graph[k].ve) //计算ve

Graph[k].ve = Graph[i].ve + p->dutt;

max_ve = Graph[k].ve;

}

}

// printf("%d---------\n", topo_num);

// exit(0);

if(topo_num < VexNum){

printf("AOE网中存在环\n");

return 1;

}

for (i = 0; i < VexNum; i++)

Graph[i].vl = max_ve;

while(flag != Topo_Stack){

i = * -- flag; //先自减,再取值

for (p = Graph[i].firstarc; p ; p = p->nextarc)

{

k = p->adjvex;

if(Graph[i].vl > Graph[k].vl - p->dutt) //计算vl

Graph[i].vl = Graph[k].vl - p->dutt;

}

}

}

void test(VNode * Graph){

int i = 0;

for (i; i < VexNum; i++)

{

printf("%d,%d\n",i,Graph[i].firstarc->adjvex);

}

}

void CriticalPath(VNode * Graph){

ArcNode * p;

int i,e,l,k;

for (i = 0; i < VexNum; i++)

{

for (p = Graph[i].firstarc; p ; p = p->nextarc)

{

k = p->adjvex;

e = Graph[i].ve;

l = Graph[k].vl-p->dutt;

if(e == l){

printf("关键活动:%d---->%d\n",i,k);

}

}

}

}

void main()

{

printf("输入事件总数:");

scanf("%d",&VexNum);

printf("输入活动总数:");

scanf("%d",&ArcNum);

VNode * Graph = (VNode *)malloc(VexNum*sizeof(VNode));

CreatGraph(Graph);

TopologicalOrder(Graph);

CriticalPath(Graph);

free(Graph);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息