工程【拓扑排序】

Time Limit:10000MS Memory Limit:256000K
Total Submit:46 Accepted:33
Case Time Limit:1000MS


Description
张三是某工程公司的项目工程师。一天公司接下一项大型工程,该公司在大型工程的施工前,先要把整个工程划分为若干个子工程,并把这些子工程编号为 1 、 2 、 … 、 N 1、2、…、N 12N;这样划分之后,子工程之间就会有一些依赖关系,即一些子工程必须在某些子工程完成之后才能施工,公司需要工程师张三计算整个工程最少的完成时间。
对于上面问题,可以假设:
1、根据预算,每一个子工程都有一个完成时间。
2、子工程之间的依赖关系是:部分子工程必须在一些子工程完成之后才开工。
3、只要满足子工程间的依赖关系,在任何时刻可以有任何多个子工程同时在施工,也即同时施工的子工程个数不受限制。
例如:有五个子工程的工程规划表:
现在对于给定的子工程规划情况,及每个子工程完成所需的时间,如果子工程划分合理则求出完成整个工程最少要用的时间,如果子工程划分不合理,则输出 − 1 -1 1


Input
1 1 1行为正整数 N N N,表示子工程的个数 ( N < = 200 ) (N<=200) N<=200
2 2 2行为 N N N个正整数,分别代表子工程 1 、 2 、 … 、 N 1、2、…、N 12N的完成时间。
3 3 3行到 N + 2 N+2 N+2行,每行有 N − 1 N-1 N1 0 0 0 1 1 1,其中的第 K + 2 K+2 K+2行的这些 0 0 0 1 1 1,分别表示“子工程K”与子工程 1 、 2 、 … 、 K − 1 、 K + 1 、 … 、 N 1、2、…、K-1、K+1、…、N 12K1K+1N的依赖关系 ( K = 1 、 2 、 … 、 N ) (K=1、2、…、N) K=12N。每行数据之间均用空格分开。

Output
如果子工程划分合理则输出完成整个工程最少要用的时间,如果子工程划分不合理,则输出 − 1 -1 1


Sample Input
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.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

Sample Output
project.out
14

project.out
-1


解题思路
做一个拓扑排序,从顶头的那个没有前提条件的工程开始做.
输出 − 1 -1 1的情况只有一个,图中出现环,那么拓扑排序无法排序到所有点,只需要特判这个就好了。

拓扑排序:
在这里插入图片描述
详见 博客.


代码

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n,bsy[220],a[220][220],v[220],h,t,sum,ans,f[220],q[220];
void bfs(){//这段代码利用广度优先搜索,做到了在O(V+E)的时空复杂度内完成拓扑排序。
	while(h<t){
		h++;
		for(int i=1;i<=n;i++)
			if(q[h]!=i)
				if(a[i][q[h]])
				{
					v[i]--;
					if(!v[i])
					{
						q[++t]=i;
						sum--;
					}
					f[i]=max(f[i],f[q[h]]+bsy[i]);//取max是因为必须在前提条件最后的那个完成时间才可能做i
				}
	}
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&bsy[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])
					v[i]++;
			}
		}
	}	
	sum=n;
	for(int i=1;i<=n;i++)
		if(!v[i])//没有入度代表没有前提条件,可以直接做
		{
			q[++t]=i;
			sum--;
			f[i]=bsy[i];
		}
	bfs();
	for(int i=1;i<=n;i++)
		ans=max(ans,f[i]);
	if(sum) printf("-1");
	else printf("%d",ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的体育馆管理系统,源码+数据库+毕业论文+视频演示 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本体育馆管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据信息,使用这种软件工具可以帮助管理人员提高事务处理效率,达到事半功倍的效果。此体育馆管理系统利用当下成熟完善的SpringBoot框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线选择试题并完成答题,在线查看考核分数。管理员管理收货地址管理、购物车管理、场地管理、场地订单管理、字典管理、赛事管理、赛事收藏管理、赛事评价管理、赛事订单管理、商品管理、商品收藏管理、商品评价管理、商品订单管理、用户管理、管理员管理等功能。体育馆管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 关键词:体育馆管理系统;SpringBoot框架;Mysql;自动化
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值