工 程 工程 工程
题目
张三是某工程公司的项目工程师。一天公司接下一项大型工程,该公司在大
型工程的施工前,先要把整个工程划分为若干个子工程,并把这些子工程编号为
1、2、„、N;这样划分之后,子工程之间就会有一些依赖关系,即一些子工程
必须在某些子工程完成之后才能施工,公司需要工程师张三计算整个工程最少的
完成时间。
对于上面问题,可以假设:
1、根据预算,每一个子工程都有一个完成时间
2、子工程之间的依赖关系是:部分子工程必须在一些子工程完成之后才开
工
3、只要满足子工程间的依赖关系,在任何时刻可以有任何多个子工程同时
在施工,也即同时施工的子工程个数不受限制
例如:有五个子工程的工程规划表:
序号 | 完成时间 | 子工程 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 |
其中,表格中第
K
+
1
K+1
K+1 行
J
+
2
J+2
J+2 列的值为
0
0
0 表示“子工程
K
K
K”可以在“子工程
J
J
J”
没完成前施工,为
1
1
1 表示“子工程
K
K
K”必须在“子工程
J
J
J”完成后才能施工
上述工程最快完成时间为
14
14
14 天
又例如,有五个子工程的工程规划表:
序号 | 完成时间 | 子工程 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 |
上述的子工程划分不合理,因为无法安排子工程
1
,
3
,
4
1,3,4
1,3,4 的施工
现在对于给定的子工程规划情况,及每个子工程完成所需的时间,如果子工
程划分合理则求出完成整个工程最少要用的时间,如果子工程划分不合理,则输出
−
1
-1
−1
输入
第
1
1
1 行为正整数
N
N
N,表示子工程的个数
(
N
<
=
200
)
(N<=200)
(N<=200) 第
2
2
2 行为
N
N
N 个正整数
分别代表子工程
1
、
2
、
„
N
1、2、„N
1、2、„N 的完成时间
第
3
3
3 行到
N
+
2
N+2
N+2 行,每行有
N
−
1
N-1
N−1 个
0
0
0 或
1
1
1,其中的第
K
+
2
K+2
K+2 行的这些
0
0
0 或
1
1
1
分别表示“子工程
K
K
K”与子工程
1
、
2
、
„
、
K
−
1
、
K
+
1
、
„
、
N
1、2、„、K-1、K+1、„、N
1、2、„、K−1、K+1、„、N 的依赖关系
(
K
=
1
、
2
、
„
、
N
)
(K=1、2、„、N)
(K=1、2、„、N) 每行数据之间均用空格分开
输出
如果子工程划分合理则输出完成整个工程最少要用的时间,如果子工程划分
不合理,则输出
−
1
-1
−1
输入样例
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
project.in
5
5 4 12 7 2
0 1 0 0
0 0 0 0
0 0 1 0
1 1 0 0
1 1 1 1
project.out
-1
解题思路
就拓扑排序吧
程序如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
queue<int>q;
int n, t[10001], f[10001], a[201][201], d[10001], ans;
void tuopu()
{
while(!q.empty())
{
int p = q.front();
q.pop();
for(int i = 1; i <= n; ++i)
{
if(a[i][p])
{
d[i]--;
t[i] = max(t[i], t[p] + f[i]);
if(!d[i]) q.push(i);
}
}
}
}
int main()
{
freopen("project.in","r",stdin);
freopen("project.out","w",stdout);
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
scanf("%d",&f[i]);
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= n; ++j)
{
if(i != j)
{
scanf("%d",&a[i][j]);
if(a[i][j]) d[i]++;
}
}
}
for(int i = 1; i <= n; ++i)
{
if(!d[i])
{
q.push(i);
t[i] = f[i];
}
}
tuopu();
for(int i = 1; i <= n; ++i)
{
if(d[i])
{
printf("-1");
return 0;
}
}
for(int i = 1; i <= n; ++i)
ans = max(ans, t[i]);
printf("%d",ans);
fclose(stdin);
fclose(stdout);
return 0;
}