#include<iostream>
#include<string.h>
using namespace std;
#define Maxn 100 //顶点最大数
#define Maxm 200 //边数最大数
struct arcnode{
int to,dur,no; //边指向点,以及权重(时间),活动序号
arcnode *next;
};
int n,m; //顶点数,边数
arcnode *list1[Maxn]; //出边邻接表
arcnode *list2[Maxm]; //入边邻接表
int count1[Maxn] ; //入度
int count2[Maxm] ; //出度
int ee[Maxn]; //各事件的最早可能开始时间
int le[Maxn]; //各事件的最迟允许开始时间
int e[Maxm]; //各活动的最早可能开始时间
int l[Maxm]; //各活动的最迟允许开始时间
void create(){ //构建邻接表
int i,u,v,w; //循环变量以及边起点 边终点 边时间
printf("请输入顶点数和边数\n");
scanf("%d%d",&n,&m);//读入顶点数和边数
memset(list1,0,sizeof(list1)) ;//初始化数组
memset(list2,0,sizeof(list2)) ;
memset(count1,0,sizeof(count1));
memset(count2,0,sizeof(count2));
arcnode *temp1 ,*temp2;
printf("请输入边起点 边终点 边时间\n");
for(i=0;i<m;i++){
scanf("%d%d%d",&u,&v,&w);//读入边的起点和终点
count1[v]++;
count2[u]++;
temp1=new arcnode;
temp1->to=v;
temp1->no=i+1;
temp1->dur=w;
temp1->next=NULL;
if(list1[u]==NULL)list1[u]=temp1;
else{temp1->next=list1[u];//头插法构建出边邻接表
list1[u]=temp1;
}
temp2=new arcnode;
temp2->to=u;
temp2->no=i+1;
temp2->dur=w;
temp2->next=NULL;
if(list2[v]==NULL)list2[v]=temp2;
else{temp2->next=list2[v];
list2[v]=temp2;
}
}
printf("打印AOE网的邻接表逻辑图\n");
for(i=0;i<n;i++){
temp1=list1[i];
printf("%d %d",count1[i],i);
cout<<"-->";
while(temp1!=NULL){
printf("[%d %d]",temp1->to,temp1->dur);
temp1=temp1->next;
}
printf("\n");
}
printf("\n");
}
void CriticalPath(){//关键路径算法
int i,j,k;
arcnode *temp1,*temp2;
memset(ee,0,sizeof(ee));
memset(le,0,sizeof(le));
//拓扑排序
int top1=-1;
int stack[200]; //一个栈
//拓扑排序
for(i=0;i<n;i++){
if(count1[i]==0)stack[++top1]=i;
}
while(top1>-1){
i=stack[top1--];
temp1=list1[i];
while(temp1!=NULL){
j=temp1->to;
count1[j]--;
if(ee[i]+temp1->dur>ee[j])ee[j]=ee[i]+temp1->dur;
if(count1[j]==0)stack[++top1]=j;
temp1=temp1->next;
}
}
//运用逆邻接表来进行逆拓扑排序
int top2=-1;
for(i=0;i<n;i++){
le[i]=ee[n-1];
if((count2[i]==0))stack[++top2]=i;
}
while(top2>-1){
i=stack[top2--];
temp2=list2[i];
while(temp2!=NULL){
j=temp2->to;
count2[j]--;
if(le[i]-temp2->dur<le[j])le[j]=le[i]-temp2->dur;
if(count2[j]==0)stack[++top2]=j;
temp2=temp2->next;
}
}
memset(e, 0, sizeof(e));
memset(l, 0, sizeof(l));
printf("关键路径如下\n");
//
for(i=0;i<n;i++){
temp1=list1[i];
while(temp1!=NULL){
j=temp1->to;
k=temp1->no;
e[k]=ee[i];
l[k]=le[j]-temp1->dur;
if(e[k]==l[k]){
printf("v%d : %d->%d\n",k,i,j);
}
temp1=temp1->next;
}
}
printf("\n");
printf("最短时间:%d",ee[n-1]);
}
int main(){
create();
CriticalPath() ;
return 0;
}