ccf训练计划

问题背景
西西艾弗岛荒野求生大赛还有 n nn 天开幕!

问题描述
为了在大赛中取得好成绩,顿顿准备在 n nn 天时间内完成“短跑”、“高中物理”以及“核裂变技术”等总共 m mm 项科目的加强训练。其中第 i ii 项(1 ≤ i ≤ m 1 \le i \le m1≤i≤m)科目编号为 i ii,也可简称为科目 i ii。已知科目 i ii 耗时 t i t_it 
i

  天,即如果从第 a aa 天开始训练科目 i ii,那么第 a + t i − 1 a + t_i - 1a+t 
i

 −1 天就是该项训练的最后一天。

大部分科目的训练可以同时进行,即顿顿在同一天内可以同时进行多项科目的训练,但部分科目之间也存在着依赖关系。如果科目 i ii 依赖科目 j jj,那么只能在后者训练结束后,科目 i ii 才能开始训练。具体来说,如果科目 j jj 从第 a aa 天训练到第 a + t j − 1 a + t_j - 1a+t 
j

 −1 天,那么科目 i ii 最早只能从第 a + t j a + t_ja+t 
j

  天开始训练。还好,顿顿需要训练的 m mm 项科目依赖关系并不复杂,每项科目最多只依赖一项别的科目,且满足依赖科目的编号小于自己。那些没有任何依赖的科目,则可以从第 1 11 天就开始训练。

对于每一项科目,试计算:

1)最早开始时间:该科目最早可以于哪一天开始训练?

2)最晚开始时间:在不耽误参赛的前提下(n nn 天内完成所有训练),该科目最晚可以从哪一天开始训练?

n nn 天内完成所有训练,即每一项科目训练的最后一天都要满足 ≤ n \le n≤n。需要注意,顿顿如果不能在 n nn 天内完成全部 m mm 项科目的训练,就无法参加大赛。这种情况下也就不需要再计算“最晚开始时间”了。

输入格式
从标准输入读入数据。

输入共三行。

输入的第一行包含空格分隔的两个正整数 n nn 和 m mm,分别表示距离大赛开幕的天数和训练科目的数量。

输入的第二行包含空格分隔的 m mm 个整数,其中第 i ii 个(1 ≤ i ≤ m 1 \le i \le m1≤i≤m)整数 p i p_ip 
i

  表示科目 i ii 依赖的科目编号,满足 0 ≤ p i < i 0 \le p_i < i0≤p 
i

 <i;p i = 0 p_i = 0p 
i

 =0 表示科目 i ii 无依赖。

输入的第三行包含空格分隔的 m mm 个正整数,其中第 i ii 个(1 ≤ i ≤ m 1 \le i \le m1≤i≤m)数 t i t_it 
i

  表示训练科目 i ii 所需天数,满足 1 ≤ t i ≤ n 1 \le t_i \le n1≤t 
i

 ≤n。

输出格式
输出到标准输出中。

输出共一行或两行。

输出的第一行包含空格分隔的 m mm 个正整数,依次表示每项科目的最早开始时间。

如果顿顿可以在 n nn 天内完成全部 m mm 项科目的训练,则继续输出第二行,否则输出到此为止。

输出的第二行包含空格分隔的 m mm 个正整数,依次表示每项科目的最晚开始时间。

样例 1 输入
10 5
0 0 0 0 0
1 2 3 2 10
1
2
3
样例 1 输出
1 1 1 1 1
10 9 8 9 1
1
2
样例 1 说明
五项科目间没有依赖关系,都可以从第 1 11 天就开始训练。

10 1010 天时间恰好可以完成所有科目的训练。其中科目 1 11 耗时仅 1 11 天,所以最晚可以拖延到第 10 1010 天再开始训练;而科目 5 55 耗时 10 1010 天,必须从第 1 11 天就开始训练。

样例 2 输入
10 7
0 1 0 3 2 3 0
2 1 6 3 10 4 3
1
2
3
样例 2 输出
1 3 1 7 4 7 1
1
样例 2 说明
七项科目间的依赖关系如图所示,其中仅科目 5 55 无法在 10 1010 天内完成训练。

具体来说,科目 5 55 依赖科目 2 22、科目 2 22 又依赖于科目 1 11,因此科目 5 55 最早可以从第 4 44 天开始训练。

样例 3 输入
10 5
0 1 2 3 4
10 10 10 10 10
1
2
3
样例 3 输出
1 11 21 31 41
1
子任务
70 % 70\%70% 的测试数据满足:顿顿无法在 n nn 天内完成全部 m mm 项科目的训练,此时仅需输出一行“最早开始时间”;

全部的测试数据满足 0 < n ≤ 365 0 < n \le 3650<n≤365 且 0 < m ≤ 100 0 < m \le 1000<m≤100。

代码:

#include <stdio.h>
#include<iostream>
using namespace std;
const int N=10010;
int main() {
    int n,m;
	cin>>n>>m;
	int p[m];
	int t[m];
	for(int i=0;i<m;i++){
		cin>>p[i];
	}
	for(int i=0;i<m;i++){
		cin>>t[i];
	}
		int start[m],end[m];
		start[0]=1;
		end[0]=t[0];
		for(int i=1;i<m;i++){
			if(p[i]){
				start[i]=end[p[i]-1]+1;
			}
			else start[i]=1;
			end[i]=start[i]+t[i]-1;
		}
		for(int i=0;i<m;i++){
			cout<<start[i]<<" ";
		}
	return 0;
}

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值