【无标题】

ds-工程最短消耗

总提交数: 1615次通过数: 560次通过率: 34.67%

内存限制: 10485760(BYTE)时间限制: 1000(MS)输入限制: 1000(行)输出限制: 1000(行)

题目描述

给出一个工程中N个阶段的时间消耗和依赖关系,试求出工程的最短时间消耗。

Input Format

输入N 0<N<=20。

随后输入N行数据,每行包含从1起始的阶段编号S、时间消耗T、以及用分号隔开的所依赖的不同阶段编号【如果不依赖其他阶段则此项为空】

Output Format

输出一行,为完成N个阶段的时间消耗。如果依赖关系不为DAG则输出"error"

样例输入输出

样例1
输入:
4
1 3
2 4
3 5 1;2;
4 3 3;
输出:
12
样例2
输入:
4
1 3 3;
2 4
3 5 1;2;
4 3 3;
输出:
error
这个题目最难的地方在于如何处理输入,在不确定一行会输入什么的时候,可以直接将一整行接受,使用cin.getline函数,值得注意的是,需要在前面加一个getchar(),如果不加,getline会读取第一行而出现错误。
#include<iostream>
using namespace std;
int main() {
	int n;
	cin >> n;
	getchar();
	int* indegree = new int[n];
	int* cost = new int[n];
	int** a = new int* [n];
	int* visited = new int[n];
	for (int i = 0; i < n; i++) {
		indegree[i] = 0;
		cost[i] = 0;
		a[i] = new int[n];
		visited[i] = 0;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			a[i][j] = 0;
		}
	}
	char input[100];
	for (int i = 0; i < n; i++) {
		cin.getline(input, 100);
		int start;
		int j = 0;
		int u;
		int t = 0;
		int n = 0;
		while (1) {
			if (input[j] - '0' >= 0 && input[j] - '0' <= 9) {
				t++;
				if (t == 1)
					u = input[j] - '0';
				else {
					u = u * 10 + input[j]-'0';
					t = 0;
				}
			}
			if (input[j] == ' ' || input[j] == ';') {
				n++;
				t = 0;
				if (n == 1) {
					start = u - 1;
				}
				else if (n == 2) {
					cost[start] = u;
				}
				else if(input[j]!='\n') {
					a[u - 1][start] = 1;
					indegree[start]++;
				}
			}
			else if (input[j] == 0) {
				if (n == 1)
					cost[start] = u;
				break;
			}
			j++;
		}
	}
	int* final = new int[n];
	for (int i = 0; i < n; i++) {
		final[i] = 0;
	}
	int* stack = new int[n];
	int start = 0;
	int end = -1;
	for (int i = 0; i < n; i++) {
		if (indegree[i] == 0) {
			end++;
			stack[end] = i;
			visited[i] = 1;
			break;
		}
	}
	while (1) {
		int t = stack[start];
		start++;
		for (int i = 0; i < n; i++) {
			if (a[t][i] != 0) {
				indegree[i]--;
				int u = final[t] + cost[t];
				if (u > final[i])
					final[i] = u;
			}
		}
		for (int i = 0; i < n; i++) {
			if (indegree[i] == 0 && visited[i] == 0) {
				end++;
				stack[end] = i;
				visited[i]++;
			}
		}
		if (start > end)
			break;
	}
	int max = 0;
	int t = 0;
	for (int i = 0; i < n; i++)
		if (final[i] > max) {
			max = final[i];
			t = i;
		}
	if (start == n)
		cout << max + cost[t];
	else
		cout << "error";
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值