//AOE_求关键路径_基于邻接表 //首先用正向邻接表求出每个活动的最早发生时间 // 用逆向邻接表求出每个活动的最迟发生时间 //再两者对应相减,为0即为活动的关键活动 // //大纲:删除无前继结点的顶点 // //输入: // 先确定顶点数和边数 // 分为头结点和值结点,头结点含有count,用于计数这个结点当前含有的前继 // //求出每个活动的最早发生时间的时候,当前路径小于新的时候,更换 //求出每个活动的最迟发生时间的时候,当前路径大于新的时候,更换 // // 使用栈记录count为0的结点,栈空时结束 // 当count--后为0,说明这个结点的前继处理完了,把这个结点放入栈里 //(由于关键路径既是最长路径,所以可以增加代码,保留合理的前继就可以知道路上的关键活动了) /* 9 11 0 1 6 0 2 4 0 3 5 1 4 1 2 4 1 3 5 2 4 6 9 4 7 7 5 7 4 6 8 2 7 8 4 035214768 875364210 earliest0 -latest0 0 - 0 = 0 earliest1 -latest1 6 - 6 = 0 earliest2 -latest2 4 - 6 = -2 earliest3 -latest3 5 - 8 = -3 earliest4 -latest4 7 - 7 = 0 earliest5 -latest5 7 - 10 = -3 earliest6 -latest6 16 - 16 = 0 earliest7 -latest7 14 - 14 = 0 earliest8 -latest8 18 - 18 = 0 Press any key to continue */ #include <iostream> using namespace std; typedef struct zhinode *zhinode_pointer; struct zhinode////////////值结点 { zhinode(){link=NULL;} int var; int length; zhinode_pointer link; }; struct heapnode///////////头结点 { heapnode(){count=0;link=NULL;} int count; zhinode_pointer link; }; void draw(struct heapnode *&,struct heapnode *&);//绘图 void insert(struct heapnode *heap,int a,int b,int c);//连接值结点 void deal_first(struct heapnode *,int *&);// void deal_second(struct heapnode *,int *&,int *&);// void out(int *a,int *b); int v,edge; int main(int argc, char const *argv[]) { struct heapnode *first,*second; draw(first,second); int *earliest; deal_first(first,earliest); cout<<endl; int *latest; deal_second(second,latest,earliest); cout<<endl; out(earliest,latest); return 0; } void draw(struct heapnode * &first,struct heapnode * &second)//绘图 { int i; int spot1,spot2,len; cin>>v>>edge;///输入点数目 first=new struct heapnode[v]; second=new struct heapnode[v]; for (i = 0; i < edge; ++i) { cin>>spot1>>spot2>>len; insert(first,spot1,spot2,len); insert(second,spot2,spot1,len); } } void insert(struct heapnode *heap,int a,int b,int c) { heap[b].count++;//b的前继加1 zhinode_pointer ok=new struct zhinode;//增加值结点 if(ok==NULL)cerr<<"申请失败"; ok->var=b; ok->length=c;//给值结点赋值 zhinode_pointer item=heap[a].link; if(item==NULL)heap[a].link=ok;//无链时 else{//////////////////////////有链时 zhinode_pointer dangqian=item; while(item) { dangqian=item; item=item->link; } dangqian->link=ok; } } ///-------------------------------------------------------------/// void deal_first(struct heapnode *heap,int *&earliest)// { int* zhan=new int[v]; int zhan_top=0; int temp;//记录当前正在使用的头结点的位置 earliest=new int[v]; for (int i = 0; i < v; ++i) { if(heap[i].count==0)zhan[zhan_top++]=i;//count为0时。进栈; earliest[i]=0; } if(zhan_top==0 || zhan_top >=2)cerr<<"error,没有头结点或不只有一个头结点"; zhinode_pointer will_free; zhinode_pointer item; while(zhan_top!=0)//有结点在栈里 { will_free=heap[ zhan[--zhan_top] ].link;//要删除的值结点 temp=zhan[zhan_top]; cout<<temp;//输出某个工程 while(will_free != NULL)//要删除的开始结点不为空 { if ((earliest[temp] + will_free->length) > earliest[will_free->var])//路径更长,路径长度更换,可以增加代码用于记录合理的前继 earliest[will_free->var] = earliest[temp] + will_free->length; item=will_free->link;//下一个值结点 if( !--heap[will_free->var].count )zhan[zhan_top++]=will_free->var;//当count为0时,说明前继处理完了,进栈。 delete will_free;//删除值结点 will_free=item; } } delete zhan; } void deal_second(struct heapnode *heap,int *&latest,int *&earliest)// { int* zhan=new int[v]; int zhan_top=0; int temp;//记录当前正在使用的头结点的位置 latest=new int[v]; for (int i = 0; i < v; ++i) { if(heap[i].count==0)zhan[zhan_top++]=i;//count为0时。进栈; latest[i]=earliest[v-1];//必须有这句开头啊 } if(zhan_top==0 || zhan_top >=2)cerr<<"error,没有头结点或不只有一个头结点"; zhinode_pointer will_free; zhinode_pointer item; while(zhan_top!=0)//有结点在栈里 { will_free=heap[ zhan[--zhan_top] ].link;//要删除的值结点 temp=zhan[zhan_top]; cout<<temp;//输出某个工程 while(will_free != NULL)//要删除的开始结点不为空 { if ((latest[temp] - will_free->length) < latest[will_free->var])//路径更长,路径长度更换,可以增加代码用于记录合理的前继 latest[will_free->var] = latest[temp] - will_free->length; item=will_free->link;//下一个值结点 if( !--heap[will_free->var].count )zhan[zhan_top++]=will_free->var;//当count为0时,说明前继处理完了,进栈。 delete will_free;//删除值结点 will_free=item; } } delete zhan; } void out(int *a,int *b) { for (int i = 0; i < v; ++i) { cout<<"earliest"<<i<<" -latest"<<i<<" "<<a[i]<<" - "<<b[i]<<" = "<<a[i]-b[i]<<endl; } }
原文:http://blog.csdn.net/h1023417614/article/details/20159745