CCF-CSP 202212-02 训练计划

CCF-CSP 202212-2 训练计划

题目链接

子任务

  1. 70 % 70\% 70%的测试数据满足:顿顿无法在 n n n天 内完成全部 m m m 项科目的训练,此时仅需输出一行“最早开始时间”;

  2. 全部的测试数据满足 0 < n ≤ 365 0<n\leq365 0<n365 0 < m ≤ 100 0<m\leq100 0<m100

题目背景

本题的题目背景是AOE网

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在上述AOE网中,ve 表示最早开始时间,vl 表示最迟开始时间。事件 k k k最早开始时间 v e ( k ) ve(k) ve(k),是从源点到顶点 k k k 的最长路径长度。最迟开始时间 v l ( k ) vl(k) vl(k) 等于整个工程的关键路径从源点到汇点的最长路径)长度减去从顶点 k k k 到汇点的最长路径的长度。

(参考《数据结构:抽象建模、实现与应用》孙涵,黄元元,高航,秦小麟编著.机械工业出版社,2020 p. 113-126)

解题思路

针对子任务1,思路较为简单,不过多赘述。要通过所有样例,难点在于计算出最迟开始时间,解题步骤如下:

  1. 计算出样例是否能在规定的 n n n 天内完成项目训练
  2. 若不能,仅输出最早开始时间
  3. 若能,计算各项目的被依赖关系(eg,项目j依赖于项目i,则i需要先完成,再完成j,被依赖关系是项目i被j依赖)
  4. 若项目i被j依赖,最迟开始时间的计算公式为:vl[i]=min(vl[j]-day[i],vl[i]);
  5. 若项目i没有存在被依赖关系,则最迟开始时间的计算公式为:vl[i]=max_day-day[i];
  6. 注意,因为项目训练首天为第一天,所以 max_day=n+1;

满分题解

#include <iostream>
using namespace std;
#include <unordered_map>
#include <vector>

int p[101];
int ve[101];
int vl[101];
int day[101];

unordered_map<int,vector<int>> q;

int main(int argc, char const *argv[])
{
    int n,m;
    int max_day = -1;
    bool flag = true;
    cin >> n >> m;
    int i,j;

    // 依赖关系
    for (i = 1; i <= m; i++)
    {
        cin >> p[i];
    }

    for (i = 1; i <=m; i++){
        cin >> day[i];
        if (p[i]){
            ve[i]+=ve[p[i]]+day[p[i]];
        }
        else{
            ve[i] = 1;
        }
        max_day = max(ve[i]+day[i],max_day);    // 更新关键路径长度
    }

    for (i = 1; i<=m;i++)
    {
        cout << ve[i] << " ";
    }
    
    if (max_day > n+1){
        // 无法完成任务
        flag = false;
        return 0;
    }
    max_day = n+1;
    cout << endl;
    // 可以完成任务,下面计算最晚开始时间
    // 被依赖关系
    for (i = 1; i <= m; i++){
        if (p[i]){
            // i依赖于p[i]
            // p[i]被i依赖
            q[p[i]].push_back(i);
        }
    }

    // 逆向计算最早开始时间
    for (i = m; i > 0; i--){
        if (q[i].empty()){
            // 说明没有科目依赖于科目i
            // 科目i的最迟开始时间为:max_day-day[i]
            vl[i] = max_day - day[i];
            continue;
        }
        // 存在被其他科目依赖的关系
        vl[i] = INT32_MAX;
        for (auto it : q[i])
        {
            vl[i] =min(vl[it]-day[i],vl[i]);
        }
    }
    for (i = 1; i <= m; i++){
        cout << vl[i] << " ";
    }
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值