題目:關鍵路徑尋找
對於給定的一個工程施工圖,該圖以邊爲單位從鍵盤輸入,編寫可以找出該圖的關鍵路徑的程序。
完整代碼
#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
int vex;
int dut; //持續時間
struct Node *next;
}Node;
typedef struct Hnode{
int index; //入度
int data;
Node *out;
}Hnode;
int ve[100]; //最晚發生時間
int vl[100]; //最先發生時間
int stackS[100]; //入度爲0的頂點序列棧
int stackT[100]; //逆拓撲序列棧
int topS = -1, topT = -1;
int TopoSort(Hnode A[], int m){
int i, j, k, count = 0;
Node *p;
for(i=1; i<=m; i++){
ve[i] = 0;//初始化最先發生時間
if( A[i].index==0 ){
topS++;
stackS[topS] = i;
}
}
while ( topS!=-1 ){
j = stackS[topS];
topS--;
topT++;
stackT[topT] = j;
count++;
p = A[j].out;
while (p!=NULL)
{
k = p->vex;
A[k].index--;
if( A[k].index==0 ){
topS++;
stackS[topS] = k;
}
if (ve[j] + p->dut > ve[k])
ve[k] = ve[j] + p->dut;
p = p->next;
}
}
if( count<m ) return 0;
else return 1;
}
int CriticalPath(Hnode A[], int m){
int i, j, k, dut, ei, li;
Node *p;
if( !TopoSort(A, m) ){
printf("* 工程圖中存在環,無關鍵路徑。\n");
return 0;
}
for(i=1;i<=m;i++)
vl[i] = ve[m]; //始化爲最先發生時間
while( topT!=-1 ){
j = stackT[topT];
topT--; //按逆拓撲順序求各頂點的vl
p = A[j].out;
while( p!=NULL){
k = p->vex;
if( vl[k] - p->dut < vl[j] )
vl[j] = vl[k] - p->dut;
p = p->next;
}
}
printf("* 關鍵路徑(標記爲'*')以下:\n\n");
for(j=1;j<=m;j++){
p = A[j].out;
while( p!=NULL ){
k = p->vex;
dut = p->dut;
ei = ve[j];
li = vl[k] - dut;
if( ei==li )
printf("* <%d, %d>: dut=%d, e(i)=%d, l(i)=%d\n", A[j].data, A[k].data, dut, ei, li);
else printf(" <%d, %d>: dut=%d, e(i)=%d, l(i)=%d\n", A[j].data, A[k].data, dut, ei, li);
p = p->next;
}
}
}
void main(){
int m, n, i;
printf("* 請輸入頂點個數:");
scanf("%d",&m);
printf("* 請輸入邊的條數:");
scanf("%d",&n);
Hnode A[m+1];
for(i=1;i<=m;i++){
A[i].index = 0;
A[i].data = i;
A[i].out = NULL;
}
int u, v, w;
Node *p;
printf("* 請輸入%d條邊以及該邊的權:\n", n);
for(i=0;i<n;i++){
scanf("%d%d%d",&u,&v,&w);//讀入各邊以及邊的權值
p = (Node*)malloc( sizeof(Node) );
A[v].index++;
p->vex = v;
p->dut = w;
p->next = A[u].out;
A[u].out = p;
}
CriticalPath(A, m);
}
參考資料
西北大學MOOC:拓撲排序
西北大學MOOC:關鍵路徑node