CCF 2022.12.2 训练计划

分析

  1. 计算最早开始的时间
    a. 不依赖于任何结点:第一天开始
    b. 等于依赖的结点结束的那天
  2. 计算最晚开始的时间
    a. 不被依赖:最后一天-自己训练时间+1
    b. 被依赖:
    注意!需要考虑被多个结点依赖
    因此遍历,寻找那些依赖结点最晚开始训练时间的最小值Min,自己就等于=Min-自己训练时间+1

最后判断能不能训练完,来决定是否输出就好。

实现思路

因此非常需要前期的数据结构和数据处理支撑:

  1. 结构体:
//一定要考虑一个节点被多个节点依赖的情况! 
class node {
	public:
		int day;//该任务的训练时间 
		int depend;//节点i依赖于哪个节点? 
		int depended[N];//节点i被哪个节点依赖? 
		int s;//最早开始训练的时间 
		int f;//最晚开始训练的时间
		int k;//被几个依赖 
		//构造函数初始化 
		node() {
			depend=depended[0]=-1;
			k=s=f=0;
		};
};
  1. 记录依赖和被依赖
//处理依赖的数据 
	for(int i=0; i<m; i++) {
		cin>>x;
		a[i].depend=x-1;//节点i依赖于节点x-1
		if(x!=0) {
			a[x-1].depended[a[x-1].k++]=i;//节点x-1被节点i依赖 
			} 
	}

完整代码

#include<iostream>
#include<algorithm>
#include<math.h>
#define N 102
using namespace std;
//一定要考虑一个节点被多个节点依赖的情况! 
class node {
	public:
		int day;//该任务的训练时间 
		int depend;//节点i依赖于哪个节点? 
		int depended[N];//节点i被哪个节点依赖? 
		int s;//最早开始训练的时间 
		int f;//最晚开始训练的时间
		int k;//被几个依赖 
		//构造函数初始化 
		node() {
			depend=depended[0]=-1;
			k=s=f=0;
		};
};

int n,m;//n天 m个任务
node a[N];

int main() {
	cin>>n>>m;
	int x;
	
	//处理依赖的数据 
	for(int i=0; i<m; i++) {
		cin>>x;
		a[i].depend=x-1;//节点i依赖于节点x-1
		if(x!=0) {
			a[x-1].depended[a[x-1].k++]=i;//节点x-1被节点i依赖 
			} 
	}
	for(int i=0; i<m; i++) 
		cin>>a[i].day;//输入每个任务训练天数 
	
	//计算最早开始时间 
	for(int i=0; i<m; i++) {
		if(a[i].depend==-1) {//不依赖于任何节点 
			a[i].s=1;//第一天开始 
		} 
		else {//依赖于节点 a[i].depen 
		//因此第一天=该节点s+该节点day 
			a[i].s=a[a[i].depend].s+a[a[i].depend].day;
		}
	}
	
	//计算最晚时开始时间
	for(int i=m-1; i>=0; i--) {
		if(a[i].depended[0]==-1) {//不被依赖
			a[i].f=n-a[i].day+1;//最后一天-训练时间+1 
		} 
		else {//被节点 a[i].depended依赖
		//=该节点开始时间-自己训练时间
			int Min=999999;
			for(int j=0;j<a[i].k;j++){
				Min=min(Min,a[a[i].depended[j]].f);
				}
			a[i].f=Min-a[i].day;
		}
	}
	
	bool sign=true;
	for(int i=0; i<m; i++) {
		cout<<a[i].s<<" ";
		if(a[i].s+a[i].day-1>n)//判断是否能训练完,不能就不输出第二行 
			sign=false;
	}
	cout<<endl;
	
	if(sign) {
		for(int i=0; i<m; i++) {
			cout<<a[i].f<<" ";
		}
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MORE_77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值