南邮 OJ 1132 大飞机项目

大飞机项目

时间限制(普通/Java) :  3000 MS/ 9000 MS          运行内存限制 : 65536 KByte
总提交 : 80            测试通过 : 15 

比赛描述

大飞机指起飞总重超过100吨的运输类飞机,包括军用大型运输机和民用大型运输机,也包括一次航程达到3000公里的军用或100座位以上的民用客机。国际航运体系习惯上把300座位以上的客机称作“大型客机”,在我国,一般把150座以上客机称为“大型客机”。

随着民用航空快速发展和国防现代化步伐加快,中国对大型飞机的需求日益紧迫。自主研制大型飞机,发展有市场竞争力的航空产业,对于转变经济增长方式、带动科学技术发展、增强国家综合实力和国际竞争力,加快现代化步伐,具有重大意义。中国航空工业经过多年的发展,已经具备发展大型飞机的技术和物质基础。2007年2月,国务院原则批准大型飞机研制重大科技专项正式立项。

南邮 OJ 1132 大飞机项目_第1张图片


但自主制造大飞机非常复杂,需要在全球范围内配置部件,联合多个公司通力合作才能完成。假设从开始制造到完成一架飞机中间需要完成n个部件,这些部件可能由多个公司协作完成有关部分(称为一道工序),当然每道工序所耗费的时间可能是不同的。现请你根据给定数据,确定哪些工序是关键的,不能提早,也不能拖延。



输入

第一行是一个正整数:测试用例数目,最多为100。之后,每个测试用例包括多行:

l       第1行给出两个整数(空格分隔),第一个整数表示部件数n,2≤n≤200,第二个整数表示工序数m,0≤m≤20100。

l       m行,每行三个整数(空格分隔),前两个整数表示两个部件;第三个整数表示涉及上述两个部件的工序需要花费的时间t,部件用序号表示,分别为1,…,n,这里假设飞机制造启动用0号序号表示,飞机制造完成用n+1号序号表示;一道工序用前后的部件表示,例如,如果1和2部件之间存在一道工序,则这道工序表示为(1,2)

输出

对于每个测试用例:

l       按照制造顺序给出关键工序

注意:(1)每个测试用例关键工序之间没有空格;

 (2)输出部分的结尾要求包含一个多余的空行。

 (3)(4,5)和(4,7)均为关键工序时,先输出(4,7),再输出(4,5)

样例输入

2
1 2
0 1 1
1 2 2
2 4
0 1 2
1 2 3
2 3 5
0 3 18

样例输出

(0,1)(1,2)
(0,3)

题目来源

算法与数据结构设计考核赛2009




#include<iostream>
#define N 202
int main(){
	int T,n,m,i,j,t,a[N][N],earlist[N],latest[N],prev[N],next[N],temp;
	bool visited[N];
	scanf("%d",&T);
	while(T--){
		scanf("%d%d",&n,&m);
		n += 2;
		for(i=0;i<n;i++){
			for(j=0;j<n;j++){
				a[i][j]=0;
			}
			prev[i]=0;
			next[i]=0;
			earlist[i]=0;
			visited[i]=0;
			latest[i]=INT_MAX;
		}
		while(m--){
			scanf("%d%d%d",&i,&j,&t);
			a[i][j]=t;
			prev[j]++;
			next[i]++;
		}
		i=0;
		earlist[0]=0;
		visited[0]=1;
		while(i<n){
			for(j=0;j<n;j++){
				if(a[i][j]){
					prev[j]--;
					temp= earlist[i]+a[i][j];
					if(temp>earlist[j]){
						earlist[j]=temp;		//最早开始时间,算最小的
					}
				}
			}
			for(i=0;i<n;i++){
				if(!visited[i] && 0==prev[i]){
					visited[i]=1;
					break;
				}
			}
		}
		for(i=0;i<n;i++){
			visited[i] = 0;
		}
		j=n-1;
		latest[0]=0;
		latest[j]=earlist[j];
		visited[j]=1;
		while(j>0){
			for(i=n-2;i>0;i--){
				if(a[i][j]){
					next[i]--;
					temp = latest[j]-a[i][j];
					if(latest[i]>temp){
						latest[i]=temp;			//最晚开始时间,记录最小的
					}
				}
			}
			for(j=n-2;j>0;j--){
				if(!visited[j] && 0==next[j]){
					visited[j]=1;
					break;
				}
			}
		}
		t=0;							//t记录关键点个数,就存在prev好了
		for(i=0;i<n;i++){
			if(earlist[i]==latest[i]){
				prev[t++]=i;
			}
		}
		for(i=0;i<t;i++){
			for(j=t-1;j>i;j--){
				if(earlist[prev[i]]+a[prev[i]][prev[j]]==earlist[prev[j]]){
					printf("(%d,%d)",prev[i],prev[j]);
				}
			}
		}
		printf("\n");
	}
}






你可能感兴趣的:(ACM,南邮OJ,大飞机项目)