CCF-CSP 28次 第二题 【202212-2 训练计划】分享

本题链接 

#这不是一道难题,但我想分享一个使用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]);
        }

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

想在旧琴房弹不能说的秘密

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

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

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

打赏作者

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

抵扣说明:

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

余额充值