题目描述
一天公司接下一项大型工程,该公司在大型工程的施工前,先要把整个工程划分为若干个子工程,并把这些子工程编号为
这样划分之后,子工程之间就会有一些依赖关系,即一些子工程必须在某些子工程完成之后才能施工,公司需要工程师张三计算整个工程最少的完成时间。
对于上面问题,可以假设:
根据预算,每一个子工程都有一个完成时间。
子工程之间的依赖关系是:部分子工程必须在一些子工程完成之后才开工。
只要满足子工程间的依赖关系,在任何时刻可以有任何多个子工程同时在施工,也即同时施工的子工程个数不受限制。
现在对于给定的子工程规划情况,及每个子工程完成所需的时间,如果子工程划分合理则求出完成整个工程最少要用的时间,如果子工程划分不合理,则输出 。
题目解析
一个拓扑排序即可
找入度为 的工程,再求出每个工程最短的完成时间
代码
#include<cstdio>
#include<algorithm>
using namespace std;
int n,ans;
int a[205],b[205][205],f[205];
bool flag,vis[205],ff;
int main()
{
freopen("project.in","r",stdin);
freopen("project.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j) continue;
scanf("%d",&b[i][j]);
if(b[i][j]) b[i][0]++;
}
int maxn=0;
while(1)
{
maxn=1;
ff=1;
for(int i=1;i<=n;i++)
if(b[i][0]==0&&vis[i]==0)
{
maxn=0;
for(int j=1;j<=n;j++)
if(b[i][j])
maxn=max(maxn,f[j]);
f[i]=maxn+a[i];
for(int j=1;j<=n;j++)
if(b[j][i]==1&&b[j][0]!=0)
b[j][0]--;
vis[i]=1;
ff=0;
break;
}
if(ff) break;
maxn=0;
for(int i=1;i<=n;i++)
{
ans=max(ans,f[i]);
if(vis[i]==0)
maxn=1;
}
if(maxn==0)
{
flag=1;
break;
}
}
if(flag) printf("%d",ans);
else printf("-1");
}