求关键路径

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>

#define Max 30
typedef struct p1{
	int data;
	int w;
	int a;
	struct p1*next;
}bian;

typedef struct{
	int in;
	char elem;
	bian *first;
}dian;

typedef struct{
	dian data[Max];
	int d,b;
}ljb;

typedef struct s{
	int data;
	struct s*next;
}node,*stack;



void creat4(ljb &G,ljb &G1);//创建有向网的邻接表
void disp1(ljb G);
void inits(stack &S);
void pushs(stack &S,int e);
void pops(stack &S,int &e);
int emptys(stack S);
void top(ljb G,int v[]);//拓扑排序
void vee(ljb G1,ljb G,int v[],int ve[]);// 事件最早
void vll(ljb G1,ljb G,int vl[],int ve[]);// 事件最晚
void ee(ljb G,int v[],int ve[],int e[]);//活动最早
void ll(ljb G1,int v[],int vl[],int l[]);//活动最晚
//void search(ljb G1,int n,int &m,bian *p);


void inits(stack &S){
	S=NULL;}

void pushs(stack &S,int e){
	stack p;
	p=new node;
	p->data=e;
	p->next=S;S=p;
}
	

void pops(stack &S,int &e){
	stack p;p=S;
	S=p->next;
	e=p->data;
	delete p;
}

int emptys(stack S){
	if(S==NULL)return 1;
	else return 0;
}


void creat4(ljb &G,ljb &G1){//创建有向网的邻接表
	int i,j,k,w,t;
	bian *s;
	printf("请输入顶点数与边数:");
	scanf("%d %d",&G.d,&G.b);
	G1.d=G.d;
	G1.b=G.b;
	fflush(stdin);
	for(i=0;i<G.d;i++){
		printf("请输入第%d个结点的数据:",i+1);
		scanf("%c",&G.data[i].elem);
		G1.data[i].elem=G.data[i].elem;
		fflush(stdin);
		G.data[i].in=0;
		G.data[i].first=NULL;
		G1.data[i].in=0;
		G1.data[i].first=NULL;
	}
	for(k=0;k<G.b;k++){
		printf(" 请输入第条%d边依附的两个顶点及其权值极其编号:",k+1);
		scanf("%d %d %d %d",&i,&j,&w,&t);
		G.data[j-1].in++;
		s=new bian;
		s->data=j-1;s->w=w;s->a=t;
		s->next=G.data[i-1].first;
		G.data[i-1].first=s; 

	    G1.data[i-1].in++;
		s=new bian;
		s->data=i-1;s->w=w;s->a=t;
		s->next=G1.data[j-1].first;
		G1.data[j-1].first=s;
	}
}

void disp1(ljb G){
	int i;
	bian *p;
	for(i=0;i<G.d;i++){
		p=G.data[i].first;
		printf("%d %c ",G.data[i].in,G.data[i].elem);
		while(p!=NULL){
			printf("->%d %3d %3d",p->data,p->w,p->a);
		p=p->next;}printf("\n");
	}
	printf("\n");
}


void top(ljb G,int v[]){//拓扑排序
	stack S;inits(S);
	bian *p;
	int i,j,k,count=0,t=0;
	for(i=0;i<G.d;i++)
		if(G.data[i].in==0)pushs(S,i);
		while(!emptys(S)){
			pops(S,j);
			printf("%c ",G.data[j].elem);
			v[t++]=j;count++;
			p=G.data[j].first;
			while(p){
				k=p->data;
				G.data[k].in--;
				if(G.data[k].in==0){pushs(S,k);count++;}
				p=p->next;
			}
		}
		printf("\n");
		if(count<G.d)printf("出现回路!\n");
}

void vee(ljb G1,ljb G,int v[],int ve[]){// 事件最早
	int i,t,s,k=0;
	bian *p,*q;
	top(G,v);
	ve[k]=0;
	printf("%d ",ve[k]);
	for(i=1;i<G.d;i++){
		q=p=G1.data[v[i]].first;
		  k++;
		  s=0;while(p->data!=v[s])s++;
		  ve[k]=ve[s]+p->w;
		  	while(p->next!=NULL){
				t=ve[k];
			   p=p->next;
			   s=0;while(p->data!=v[s])s++;
				if((ve[s]+p->w)>t)
					t=ve[p->data]+p->w;
					}
			if(q->next!=NULL)ve[k]=t;
			printf("%d ",ve[k]);
			getch();
	}
	printf("\n");
}

void vll(ljb G1,ljb G,int vl[],int ve[]){// 事件最晚
	int i,n,s,k=0;
	int *v;
	v=new int[30];
	bian *p,*q;
	top(G,v);
	k=G.d-1;
	vl[k]=ve[k];
	for(i=G.d-2;i>=0;i--){
		q=p=G.data[v[i]].first;
		s=G.d-1;while(p->data!=v[s])s--;
		   k--;vl[k]=vl[s]-p->w;
			while(p->next!=NULL){
				n=vl[k];
				p=p->next;
		  s=G.d-1;while(p->data!=v[s])s--;
			if(vl[s]-p->w<n) n=vl[s]-p->w;
				}
			if(q->next!=NULL) vl[k]=n;
			 
	}
	for(i=0;i<G.d;i++)
		printf("%d ",vl[i]);
	printf("\n");
}

void ee(ljb G,int v[],int ve[],int e[]){//活动最早
		int i,s;
	bian *p;
	for(i=0;i<G.d;i++){
		p=G.data[i].first;
		while(p!=NULL){
			s=0;while(i!=v[s])s++;
			e[p->a]=ve[s];
		p=p->next;}
	
	}
	for(i=1;i<=G.b;i++){
			printf("a(%d) %d",i,e[i]);
			printf("\n");
	}
	printf("\n");
}

void ll(ljb G1,int v[],int vl[],int l[]){//活动最晚
	int i,j,m,s1,k=1;
	bian *p,*s;
	for(i=G1.b;i>=1;i--){
		p=NULL;m=-1;
		for(j=0;j<G1.d;j++){
		s=G1.data[j].first;
		if(s==NULL) continue;
		else{
		while(s){
			if(s->a==i){m=j;p=s;break;}
			s=s->next;}
		}
	}
		s1=G1.d-1;while(m!=v[s1])s1--;
		l[i]=vl[s1]-p->w;
			
		}
	for(i=1;i<=G1.b;i++){
			printf("l(%d) %d",i,l[i]);
			printf("\n");
	}
	printf("\n");
}



void main(){
	ljb G1,G;
	int *v,i;v=new int[30];
	int ve[30],vl[30],e[30],l[30];
	creat4(G,G1); 
	disp1(G);disp1(G1);
	vee(G1,G,v,ve);
	vll(G1,G,vl,ve);
	ee(G,v,ve,e);
	ll(G1,v,vl,l);
	printf("\n关键路径为:\n");
	for(i=1;i<=G.b;i++){
		if(e[i]==l[i])printf("%c ",G.data[v[i-1]].elem);
	}
	printf("\n");
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值