分析
- 计算最早开始的时间
a. 不依赖于任何结点:第一天开始
b. 等于依赖的结点结束的那天 - 计算最晚开始的时间
a. 不被依赖:最后一天-自己训练时间+1
b. 被依赖:
注意!需要考虑被多个结点依赖
因此遍历,寻找那些依赖结点最晚开始训练时间的最小值Min
,自己就等于=Min
-自己训练时间+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;
};
};
- 记录依赖和被依赖
//处理依赖的数据
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<<" ";
}
}
}