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

相关文章
相关标签/搜索