第一次写题解,本人也是一个小白,分享一下自己的思路,不好勿喷!!!
首先根据问题的描述很像数据结构图里的关键路径(没学过的可以去B站看王道的视频),
但是鉴于图的算法十分复杂,用在此处有点大材小用,因此我才用了关键路径的思路和回溯的算法。先求最早时间,再设置一个最大值记录,如果最大值超过比赛时间则无需计算最晚时间,最后再用回溯从最后往前遍历,把结果保存在另一个数组中以便输出,取最小值即可。代码如下:
#include<stdio.h>
typedef struct Subject{
int p;
int t;
}Subject;
int main()
{
int n,m;
int max=0;
scanf("%d%d",&n,&m);
Subject s[m+1];
for(int i=1;i<=m;i++)
scanf("%d",&s[i].p);
for(int i=1;i<=m;i++)
scanf("%d",&s[i].t);
for(int i=1;i<=m;i++){
int sum=1;
int k=i;
while(1){
if(s[k].p==0){
printf("%d ",sum);
break;
}else{
k=s[k].p;//回溯
sum+=s[k].t;
}
}
if(sum+s[i].t>max)
max=sum+s[i].t;
}
if(max-1>n)
return 0;
printf("\n");
int late[m+1];
for(int i=1;i<=m;i++)
late[i]=n;
for(int i=m;i>=1;i--){
int sum=n+1;
int k=i;
while(1){
sum-=s[k].t;
if(late[k]>sum)
late[k]=sum;
if(s[k].p==0)
break;
else
k=s[k].p;//回溯
}
}
for(int i=1;i<=m;i++)
printf("%d ",late[i]);
}