7-11 关键活动 (30 分)

假定一个工程项目由一组子任务构成,子任务之间有的可以并行执行,有的必须在完成了其它一些子任务后才能执行。“任务调度”包括一组子任务、以及每个子任务可以执行所依赖的子任务集。

比如完成一个专业的所有课程学习和毕业设计可以看成一个本科生要完成的一项工程,各门课程可以看成是子任务。有些课程可以同时开设,比如英语和C程序设计,它们没有必须先修哪门的约束;有些课程则不可以同时开设,因为它们有先后的依赖关系,比如C程序设计和数据结构两门课,必须先学习前者。

但是需要注意的是,对一组子任务,并不是任意的任务调度都是一个可行的方案。比如方案中存在“子任务A依赖于子任务B,子任务B依赖于子任务C,子任务C又依赖于子任务A”,那么这三个任务哪个都不能先执行,这就是一个不可行的方案。

任务调度问题中,如果还给出了完成每个子任务需要的时间,则我们可以算出完成整个工程需要的最短时间。在这些子任务中,有些任务即使推迟几天完成,也不会影响全局的工期;但是有些任务必须准时完成,否则整个项目的工期就要因此延误,这种任务就叫“关键活动”。

请编写程序判定一个给定的工程项目的任务调度是否可行;如果该调度方案可行,则计算完成整个工程项目需要的最短时间,并输出所有的关键活动。

输入格式:

输入第1行给出两个正整数N(100)和M,其中N是任务交接点(即衔接相互依赖的两个子任务的节点,例如:若任务2要在任务1完成后才开始,则两任务之间必有一个交接点)的数量。交接点按1~N编号,M是子任务的数量,依次编号为1~M。随后M行,每行给出了3个正整数,分别是该任务开始和完成涉及的交接点编号以及该任务所需的时间,整数间用空格分隔。

输出格式:

如果任务调度不可行,则输出0;否则第1行输出完成整个工程项目需要的时间,第2行开始输出所有关键活动,每个关键活动占一行,按格式“V->W”输出,其中V和W为该任务开始和完成涉及的交接点编号。关键活动输出的顺序规则是:任务开始的交接点编号小者优先,起点编号相同时,与输入时任务的顺序相反。

输入样例:

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

输出样例:

17
1->2
2->4
4->6
6->7
  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 
  4 const int inf=1<<30;
  5 const int maxn=500;
  6 
  7 struct vertex{
  8     int v;
  9     int w;
 10     vertex(){
 11         
 12     }
 13     
 14     vertex(int v1,int w1){
 15         v=v1;
 16         w=w1;
 17     }
 18 };
 19 
 20 
 21 int G[maxn][maxn];
 22 int inDegree[maxn];
 23 int outDegree[maxn];
 24 int ve[maxn],vl[maxn];
 25 int ansTime=-1;
 26 
 27 int n,m;
 28 stack<int> topoOrder;
 29 
 30 
 31 vector<int> vSta;
 32 vector<int> vEnd;
 33 
 34 bool solve_ve(int n){
 35     
 36     queue<int> q;
 37     
 38     for(int i=1;i<=n;i++){
 39         if(inDegree[i]==0){
 40             q.push(i);
 41         }
 42     }
 43     
 44     int cnt=0;
 45     
 46     while(!q.empty()){
 47         int u=q.front();
 48         q.pop();
 49         
 50         cnt++;
 51         
 52         for(int v=1;v<=n;v++){
 53             if(G[u][v]!=inf){
 54                 inDegree[v]--;
 55             if(inDegree[v]==0){
 56                 q.push(v);
 57             }
 58             
 59             if(ve[u]+G[u][v]>ve[v]){
 60                 ve[v]=ve[u]+G[u][v];
 61             }
 62             
 63         }
 64                 
 65         }
 66         
 67         
 68     }
 69     
 70     for(int i=1;i<=n;i++){
 71         if(ve[i]>ansTime){
 72             ansTime=ve[i];
 73         }
 74     }
 75     
 76     if(cnt==n)return true;
 77     else return false;
 78     
 79 }
 80 
 81 
 82 bool solve_vl(int n){
 83     
 84     fill(vl,vl+maxn,ansTime);
 85     
 86     queue<int> q;
 87     
 88     for(int i=1;i<=n;i++){
 89         if(outDegree[i]==0){
 90             q.push(i);
 91         }
 92     }
 93     
 94     int cnt;
 95     while(!q.empty()){
 96         int v=q.front();
 97         q.pop();
 98         
 99         cnt++;
100         
101         for(int u=1;u<=n;u++){
102             if(G[u][v]!=inf){
103                 outDegree[u]--;
104                 if(outDegree[u]==0){
105                     q.push(u); 
106                 }
107                 
108                 if(vl[v]-G[u][v]<vl[u]){
109                     vl[u]=vl[v]-G[u][v];
110                 }
111                     
112             }
113         }
114         
115     }
116     
117     if(cnt==n)return true;
118     else return false;
119     
120     
121 }
122 
123 
124 
125 int main(){
126     ifstream in("D:\\test.txt");
127     cin>>n>>m;
128     
129     fill(G[0],G[0]+maxn*maxn,inf);
130     
131     for(int i=0;i<m;i++){
132         int u,v,dis;
133         cin>>u>>v>>dis;
134         G[u][v]=dis;
135         outDegree[u]++;
136         inDegree[v]++;    
137     }
138     
139     if(!solve_ve(n)){
140         cout<<"0"<<endl;
141     }else{
142         solve_vl(n);
143         
144           cout<<ansTime<<endl; 
145         for (int i = 1; i <= n; i++)
146         {  
147             for (int j = n; j >= 1; j--)
148             {  
149                 // 活动的最早开始时间 == 活动的最迟开始时间
150                 if (G[i][j] !=inf && ve[i] == (vl[j] - G[i][j]))  
151                     printf("%d->%d\n", i, j);  
152             }  
153         }  
154         
155         
156     }
157     
158     
159     
160     
161     in.close();
162     return 0;
163 }

猜你喜欢

转载自www.cnblogs.com/moranzju/p/11387114.html