?? algo7-5.cpp
字號:
// algo7-5.cpp 求關鍵路徑。實現算法7.13、7.14的程序
#include"c1.h"
#define MAX_NAME 5 // 頂點字符串的最大長度+1
typedef int InfoType;
typedef char VertexType[MAX_NAME]; // 字符串類型
#include"c7-2.h"
#include"bo7-2.cpp"
int ve[MAX_VERTEX_NUM]; // 全局變量(用于算法7.13和算法7.14)
void FindInDegree(ALGraph G,int indegree[])
{ // 求頂點的入度,算法7.12、7.13調用
int i;
ArcNode *p;
for(i=0;i<G.vexnum;i++)
indegree[i]=0; // 賦初值
for(i=0;i<G.vexnum;i++)
{
p=G.vertices[i].firstarc;
while(p)
{
indegree[p->adjvex]++;
p=p->nextarc;
}
}
}
typedef int SElemType; // 棧類型
#include"c3-1.h"
#include"bo3-1.cpp"
Status TopologicalOrder(ALGraph G,SqStack &T)
{ // 算法7.13 有向網G采用鄰接表存儲結構,求各頂點事件的最早發生時間ve
// (全局變量)。T為拓撲序列頂點棧,S為零入度頂點棧。若G無回路,則用棧T
// 返回G的一個拓撲序列,且函數值為OK,否則為ERROR
int j,k,count,indegree[MAX_VERTEX_NUM];
SqStack S;
ArcNode *p;
FindInDegree(G,indegree);//對各頂點求入度indegree[0..vernum-1]
InitStack(S); // 初始化棧
for(j=0;j<G.vexnum;++j) // 建零入度頂點棧S
if(!indegree[j])
Push(S,j); // 入度為0者進棧
InitStack(T); // 初始化拓撲序列頂點棧
count=0; // 對輸出頂點計數
for(j=0;j<G.vexnum;++j) // 初始化ve[]=0 (最小值)
ve[j]=0;
while(!StackEmpty(S))
{ // 棧不空
Pop(S,j);
Push(T,j); // j號頂點入T棧并計數
++count;
for(p=G.vertices[j].firstarc;p;p=p->nextarc)
{ // 對j號頂點的每個鄰接點的入度減1
k=p->adjvex;
if(--indegree[k]==0) // 若入度減為0,則入棧
Push(S,k);
if(ve[j]+*(p->info)>ve[k])
ve[k]=ve[j]+*(p->info);
}
}
if(count<G.vexnum)
{
printf("此有向網有回路\n");
return ERROR;
}
else
return OK;
}
Status CriticalPath(ALGraph G)
{ // 算法7.14 G為有向網,輸出G的各項關鍵活動
int vl[MAX_VERTEX_NUM];
SqStack T;
int i,j,k,ee,el;
ArcNode *p;
char dut,tag;
if(!TopologicalOrder(G,T)) // 產生有向環
return ERROR;
j=ve[0];
for(i=1;i<G.vexnum;i++) // j=Max(ve[]) 完成點的值
if(ve[i]>j)
j=ve[i];
for(i=0;i<G.vexnum;i++) // 初始化頂點事件的最遲發生時間(最大值)
vl[i]=j; // 完成點的最早發生時間
while(!StackEmpty(T)) // 按拓撲逆序求各頂點的vl值
for(Pop(T,j),p=G.vertices[j].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
dut=*(p->info); // dut<j,k>
if(vl[k]-dut<vl[j])
vl[j]=vl[k]-dut;
}
printf(" j k dut ee el tag\n");
for(j=0;j<G.vexnum;++j) // 求ee,el和關鍵活動
for(p=G.vertices[j].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
dut=*(p->info);
ee=ve[j];
el=vl[k]-dut;
tag=(ee==el)?'*':' ';
printf("%2d %2d %3d %3d %3d %c\n",j,k,dut,ee,el,tag); // 輸出關鍵活動
}
printf("關鍵活動為:\n");
for(j=0;j<G.vexnum;++j) // 同上
for(p=G.vertices[j].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
dut=*(p->info);
if(ve[j]==vl[k]-dut)
printf("%s→%s\n",G.vertices[j].data,G.vertices[k].data); // 輸出關鍵活動
}
return OK;
}
void main()
{
ALGraph h;
printf("請選擇有向網\n");
CreateGraph(h);
Display(h);
CriticalPath(h);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -