7-11 關鍵活動(30 分)

7-11 關鍵活動(30 分)

假定一個工程項目由一組子任務構成,子任務之間有的能夠並行執行,有的必須在完成了其它一些子任務後才能執行。「任務調度」包括一組子任務、以及每一個子任務能夠執行所依賴的子任務集。數組

好比完成一個專業的全部課程學習和畢業設計能夠當作一個本科生要完成的一項工程,各門課程能夠當作是子任務。有些課程能夠同時開設,好比英語和C程序設計,它們沒有必須先修哪門的約束;有些課程則不能夠同時開設,由於它們有前後的依賴關係,好比C程序設計和數據結構兩門課,必須先學習前者。數據結構

可是須要注意的是,對一組子任務,並非任意的任務調度都是一個可行的方案。好比方案中存在「子任務A依賴於子任務B,子任務B依賴於子任務C,子任務C又依賴於子任務A」,那麼這三個任務哪一個都不能先執行,這就是一個不可行的方案。學習

任務調度問題中,若是還給出了完成每一個子任務須要的時間,則咱們能夠算出完成整個工程須要的最短期。在這些子任務中,有些任務即便推遲幾天完成,也不會影響全局的工期;可是有些任務必須準時完成,不然整個項目的工期就要所以延誤,這種任務就叫「關鍵活動」。spa

請編寫程序斷定一個給定的工程項目的任務調度是否可行;若是該調度方案可行,則計算完成整個工程項目須要的最短期,並輸出全部的關鍵活動。設計

輸入格式:

輸入第1行給出兩個正整數N(100)和M,其中N是任務交接點(即銜接相互依賴的兩個子任務的節點,例如:若任務2要在任務1完成後纔開始,則兩任務之間必有一個交接點)的數量。交接點按1~N編號,M是子任務的數量,依次編號爲1~M。隨後M行,每行給出了3個正整數,分別是該任務開始和完成涉及的交接點編號以及該任務所需的時間,整數間用空格分隔。code

輸出格式:

若是任務調度不可行,則輸出0;不然第1行輸出完成整個工程項目須要的時間,第2行開始輸出全部關鍵活動,每一個關鍵活動佔一行,按格式「V->W」輸出,其中V和W爲該任務開始和完成涉及的交接點編號。關鍵活動輸出的順序規則是:任務開始的交接點編號小者優先,起點編號相同時,與輸入時任務的順序相反。blog

輸入樣例:

7 8
1 2 4
1 3 3
2 4 5
3 4 3
4 5 1
4 6 6
5 7 5
6 7 2

輸出樣例:



解題思路:這題基本上是基於拓撲排序的。此外還定義了一個最先發生時間的數組,從1循環到n;一個最遲發生時間,逆向循環
17 1->2 2->4 4->6 6->7
1 early[i] = FindMax( early[i],early[temp]+G[temp][i] ); 2 
3 late[i] = FindMin( late[i],late[temp]-G[i][temp] );

                           這裏要注意的是最先發生時間是求幾個路線的最大數,最遲發生時間是求最小數排序

 

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 
 4 #define MAXVER 105
 5 #define INFINITY 65535
 6 
 7 int G[MAXVER][MAXVER];  //
 8 int early[MAXVER];      //最先發生時間
 9 int late[MAXVER];      //最遲發生時間
 10 int in[MAXVER];        //入度
 11 int out[MAXVER];       //出度
 12 int nv,ne;            //頂點數目 ,邊數目
 13 
 14 void CreatGraph();  15 int EarlyTime();  16 void LateTime(int Scost);  17 int FindMax( int a,int b);  18 int FindMin( int a,int b);  19 
 20 int main()  21 {  22     int flag;  23     int i,j;  24     scanf("%d %d",&nv,&ne);  25 
 26  CreatGraph();  27     flag = EarlyTime();  28     if( flag==-1)  29  {  30         printf("0\n");  31  }  32     else
 33  {  34         printf("%d\n",flag);  35  LateTime( flag );  36         for( i=1; i<=nv; i++)  37  {  38             if(early[i] != late[i])  39                 continue;  40             for( j=nv; j>=1 ; j--)  41  {  42                 if( G[i][j]>=0 && early[j]==late[j] &&late[j]-G[i][j]==early[i])  43  {  44                     //i,j均在關鍵路徑上且相鄰
 45                     printf("%d->%d\n",i,j);  46  }  47  }  48  }  49 
 50  }  51     return 0;  52 }  53 
 54 void CreatGraph()  55 {  56     int i,j;  57     int s,d,cost;  58 
 59     for( i=1; i<=nv; i++)  60  {  61         for( j=1; j<=nv; j++)  62  {  63             G[i][j] = -1;  64  }  65         early[i] = 0;  66         late[i] = INFINITY;  67         in[i] = 0;  68         out[i] = 0;  69  }  70     for( i=0; i<ne; i++)  71  {  72         scanf("%d %d %d",&s,&d,&cost);  73         G[s][d] = cost;   //有向邊
 74         in[d] ++;  75         out[s]++;  76  }  77 
 78 }  79 
 80 int EarlyTime()  81 {  82     int queue[nv];  83     int first =-1,rear = -1;  84     int count=0;  85     int i;  86     int temp,ret=0;  87 
 88     for( i=1; i<=nv; i++)  89  {  90         if( in[i]==0)  91  {  92             //若是入度爲0則入隊
 93             queue[++rear] = i;  94  }  95  }  96 
 97     while( first<rear)    //判斷隊是否爲空
 98  {  99         temp = queue[++first];   //出隊
100         count++; 101         for( i=1; i<=nv; i++) 102  { 103             if( G[temp][i]>=0 ) 104  { 105                 in[i]--; 106                 early[i] = FindMax( early[i],early[temp]+G[temp][i]); 107                 if( in[i]==0) 108  { 109                     queue[++rear] = i; 110  } 111  } 112  } 113  } 114     if( count!=nv) 115  { 116         ret = -1; 117  } 118     else
119  { 120         ret = early[1]; 121         for( i=2; i<=nv; i++) 122  { 123             if(early[i] > ret) 124  { 125                 //找出最大的early[i]
126                 ret = early[i]; 127  } 128  } 129  } 130 
131     return ret; 132 } 133 
134 void LateTime(int Scost) 135 { 136     int i; 137     int queue[MAXVER]; 138     int first=-1,rear=-1; 139     int temp; 140 
141     for( i=1; i<=nv; i++) 142  { 143         if( out[i]==0) 144  { 145             queue[++rear] = i; 146             late[i] = Scost; 147  } 148  } 149 
150     while( first<rear ) 151  { 152         temp = queue[++first]; 153         for( i=nv; i>=1; i--) 154  { 155             if( G[i][temp]>=0) 156  { 157                 late[i] = FindMin( late[i],late[temp]-G[i][temp]); 158                 out[i]--; 159                 if(out[i]==0) 160  { 161                     queue[++rear] = i; 162  } 163  } 164  } 165 
166  } 167 
168 } 169 int FindMax( int a,int b) 170 { 171     if( a>b ) 172  { 173         return a; 174  } 175     else
176  { 177         return b; 178  } 179 } 180 int FindMin( int a,int b) 181 { 182     if( a>b ) 183  { 184         return b; 185  } 186     else
187  { 188         return a; 189  } 190 }

 

 

 

PS:做爲一個剛剛接觸的渣渣,我以爲這道題有點難,作了好久,實在沒思路的話就跳過吧io

相關文章
相關標籤/搜索