#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");
}
求关键路径
最新推荐文章于 2023-10-26 22:20:51 发布