#这不是一道难题,但我想分享一个使用BFS+队列的解题思路
分析:
第一个任务较为简单,不再赘述;
在第二个任务中,要求出一个科目的最晚开始时间,应该找出依赖这个科目的所有科目,因为完成当前科目后还要去完成被依赖的所有科目。把当前科目想象为 “根”,那么“根”的被依赖路径可能会有很多条,要找出其中天数最长的一条路径,才是此科目的最晚开始时间。
思路:
根据目标科目,找出每一条依赖关系链的最末节点,节点向前寻找“父科目”是唯一的。
根据最末节点,向前遍历,直到目标科目,找出最大路径。
代码实现:
变量初始化
int n,m; //n是距离大赛开始的天数,m是训练科目的数量
scanf("%d %d",&n,&m);
int *depend = (int*)malloc(m * sizeof(int));
int *deadtime = (int*)malloc(m* sizeof(int));
int *day = (int*)malloc(m * sizeof(int));
int i;
for (i =0;i<m;i++){
deadtime[i] = n; //deadtime初始化,记录科目最晚可以开始的日期
}
for (i=0;i<m;i++){
scanf("%d",&depend[i]);
}
for (i=0;i<m;i++){
scanf("%d",&day[i]);
} //depend记录依赖关系,day记录每个项目所需的天数
准备的函数,查找判断此科目是否没有被依赖的科目
int find(int depend[],int i,int m,int start_index){ //find寻找依赖关系,start_index 为开始遍历的位置
int h;
for (h =start_index;h<m;h++){
if (depend[h] == i+1){
return h+1;
}
}
return 0;
} //若找到,返回被依赖的编号,否则返回0
队列部分:
int root_find(int depend[],int i,int m,int day[]){
int root_list[m];
root_list[0] = 1; //记录长度 //root_list第一个元素记录此数组的最长索引
int *que = (int*)malloc(100*sizeof(int)); //创建一个队列
int head = 0;//头
int tail = 0;//尾
que[tail] = i;//添加第一个元素,为起始的需要判断的索引
tail +=1;
while (head <tail){ //若head<tail则队列不为空
int flag = 0;
int h;
for (h =que[head]+1;h<m;h++){
if (depend[h] == que[head]+1){
que[tail] = h;
tail+=1;
flag = 1; //将还存在依赖关系的索引进入队列
}
}
if (!flag){ //没有往下的依赖关系了
root_list[root_list[0]] = que[head];
root_list[0] += 1;
}
head++;
}
int total = 0;
int index0;
for (index0 = 1;index0 < root_list[0]; index0++){
if (root_list[index0] == i){
return (day[i]-1);
}
else{
int temp = root_list[index0];
int temp_total = 0;
while (temp != i){ //由根向上遍历,直到头,累加积累天数
temp_total += day[temp];
temp = depend[temp] -1;
}
if (temp_total > total){
total = temp_total; //找到分支的最大路径
}
}
}
return (total+day[i]-1);
}
主函数中相应部分:
int i;
for (i =0;i<m;i++){
deadtime[i] -= root_find(depend,i,m,day);
}
for (i =0; i<m;i++){
printf("%d ",deadtime[i]);
}