码迷,mamicode.com
首页 > 其他好文 > 详细

关键子工程

时间:2015-02-28 15:55:01      阅读:627      评论:0      收藏:0      [点我收藏+]

标签:

在大型工程的施工前,我们把整个工程划分为若干个子工程,并把这些子工程编号为12……、N;这样划分之后,子工程之间就会有一些依赖关系,即一些子工程必须在某些子工程完成之后才能施工。由于子工程之间有相互依赖关系,因此有两个任务需要我们去完成:首先,我们需要计算整个工程最少的完成时间;同时,由于一些不可预测的客观因素会使某些子工程延期,因此我们必须知道哪些子工程的延期会影响整个工程的延期,我们把有这种特征的子工程称为关键子工程,因此第二个任务就是找出所有的关键子工程,以便集中精力管理好这些子工程,尽量避免这些子工程延期,达到用最快的速度完成整个工程。为了便于编程,现在我们假设:

1)根据预算,每一个子工程都有一个完成时间。

2)子工程之间的依赖关系是:部分子工程必须在一些子工程完成之后才开工。

3)只要满足子工程间的依赖关系,在任何时刻可以有任何多个子工程同时在施工,也既同时施工的子工程个数不受限制。

4)整个工程的完成是指:所有子工程的完成。

例如,有五个子工程的工程规划表:

序号

完成时间

子工程1

子工程2

子工程3

子工程4

子工程5

子工程1

5

 

0

0

0

0

子工程2

4

0

 

0

0

0

子工程3

12

0

0

 

0

0

子工程4

7

1

1

0

 

0

子工程5

2

1

1

1

1

 

其中,表格中第I+1J+2列的值如为0表示“子工程I”可以在“子工程J”没完成前施工,为1表示“子工程I”必须在“子工程J”完成后才能施工。上述工程最快完成时间为14天,其中子工程1345为关键子工程。

 

又例如,有五个子工程的工程规划表:

序号

完成时间

子工程1

子工程2

子工程3

子工程4

子工程5

子工程1

5

 

0

1

0

0

子工程2

4

0

 

0

0

0

子工程3

12

0

0

 

1

0

子工程4

7

1

1

0

 

0

子工程5

2

1

1

1

1

 

上述的子工程划分不合理,因为无法安排子工程134的施工。

 

输入数据:

1行为NN是子工程的总个数,N200。

2行为N个正整数,分别代表子工程12……、N的完成时间。

3行到N+2行,每行有N-101。其中的第I+2行的这些01,分别表示“子工程I”与子工程12…、I-1I+1…N的依赖关系,(I=12……、N)。每行数据之间均用一个空格分开。

 

输出数据:

如子工程划分不合理,则输出-1

如子工程划分合理,则用两行输出:第1行为整个工程最少的完成时间。第2行为按由小到大顺序输出所有关键子工程的编号。

 

样例:

输入文件名:project. in

5                             

5 4 12 7 2                 

0 0 0 0

0 0 0 0

0 0 0 0

1 1 0 0

1 1 1 1

 

输出文件名:project. out

14

1 3 4 5

 

题意:

  1),整个工程可划分为多个子工程,每个子工程有自己的时间,子工程之间会有依赖关系,(例如ij之前完成)

   2),整个工程完成是指所有子工程都完成

   3),计算整个过程完成的最小时间

   4),如果某些工程的时间影响整个过程完成的最小时间,这些工程被称为关键子工程。

找出所有的关键子工程。

拓扑排序,如果有环,则输出不等于输入,

根据拓扑排序的结果,

1、按f1[i]:=max{f1[j]+init[j]}ij的前驱)边境: f1[源点]:=init[源点]

   此时所求的的是每一个工程的最晚开始时间

2、按f2[i]=min{f2[j]-init[j]}ij的后缀)边境:f2[汇点]:=f1[汇点]-init[汇点]

   此时所求的是每一个工程的最早开始时间

3、如果一个工程的最早开始时间等于最晚开始时间,那这个工程为关键子工程

 

代码

var init,f1,f2:array[1..200]of longint;//f1[i]:最晚时间,f2[i]:最早时间

    i,j,k,n:longint;

    connected:array[1..200,1..200]of 0..1;

    ru,chu:array[1..200]of integer;

    used:array[1..200]of boolean;

    can:boolean;

    tuopu:array[1..200]of longint;

    son,father:array[1..200,0..200]of longint;

 

function have:boolean;

         var i:longint;

         begin have:=false;

               for i:=1 to n do

                   if (ru[i]=0)and(used[i])

                      then exit(true);

         end;

 

begin readln(n);

      for i:=1 to n do

          read(init[i]);

      fillchar(connected,sizeof(connected),0);

      for i:=1 to n do

          for j:=1 to n do

              if i<>j

                 then begin read(connected[i,j]);

                            if connected[i,j]=1

                               then begin inc(chu[j]);

                                          inc(father[j,0]);

                                          father[j,father[j,0]]:=i;

                                          inc(ru[i]);

                                          inc(son[i,0]);

                                          son[i,son[i,0]]:=j;

                                    end;

              end;

      fillchar(used,sizeof(used),true);

      k:=0;

      while have do

            begin for i:=1 to n do

                      if used[i]

                         then begin can:=false;

                                    if ru[i]=0

                                       then can:=true;

                                    if can

                                       then begin inc(k);

                                                  tuopu[k]:=i;

                                                  used[i]:=false;

                                                  for j:=1 to n do

                                                      if connected[j,i]=1

                                                         then dec(ru[j]);

                                            end;

                              end;

            end;

      if k<>n

         then begin writeln(‘-1‘);

                    halt;

              end;

     fillchar(ru,sizeof(ru),0);

     for i:=1 to n do

          for j:=1 to n do

              if i<>j

                 then begin if connected[i,j]=1

                               then inc(ru[i]);

                      end;

     k:=0;

     for i:=1 to n do

         if ru[i]=0

            then inc(k);

     for i:=1 to k do

         f1[tuopu[i]]:=init[tuopu[i]];

     for i:=k+1 to n do

         for j:=1 to son[tuopu[i],0] do

             if f1[tuopu[i]]<f1[son[tuopu[i],j]]+init[tuopu[i]]

                then f1[tuopu[i]]:=f1[son[tuopu[i],j]]+init[tuopu[i]];

     writeln(f1[tuopu[n]]);

     for i:=1 to n do

         f2[i]:=1000000000;

     f2[tuopu[n]]:=f1[tuopu[n]];

     for i:=n-1 downto 1 do

         for j:=1 to father[tuopu[i],0] do

             if f2[tuopu[i]]>f2[father[tuopu[i],j]]-init[father[tuopu[i],j]]

                then f2[tuopu[i]]:=f2[father[tuopu[i],j]]-

                                   init[father[tuopu[i],j]];

     for i:=1 to n do

         writeln(f2[i]);

     for i:=1 to n do

         if f1[i]=f2[i]

            then write(i,‘ ‘);

end.

关键子工程

标签:

原文地址:http://www.cnblogs.com/spiderKK/p/4305465.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!