【挖坑待填】PTA数据结构-08-图9 关键活动

本文介绍了一种用于工程项目中任务调度的算法,通过拓扑排序确定任务间的依赖关系,判断任务调度是否可行,计算完成整个工程项目所需的最短时间,并找出关键活动。文章提供了具体的输入输出示例及Java代码实现。

一、题目

假定一个工程项目由一组子任务构成,子任务之间有的可以并行执行,有的必须在完成了其它一些子任务后才能执行。“任务调度”包括一组子任务、以及每个子任务可以执行所依赖的子任务集。

比如完成一个专业的所有课程学习和毕业设计可以看成一个本科生要完成的一项工程,各门课程可以看成是子任务。有些课程可以同时开设,比如英语和C程序设计,它们没有必须先修哪门的约束;有些课程则不可以同时开设,因为它们有先后的依赖关系,比如C程序设计和数据结构两门课,必须先学习前者。

但是需要注意的是,对一组子任务,并不是任意的任务调度都是一个可行的方案。比如方案中存在“子任务A依赖于子任务B,子任务B依赖于子任务C,子任务C又依赖于子任务A”,那么这三个任务哪个都不能先执行,这就是一个不可行的方案。

任务调度问题中,如果还给出了完成每个子任务需要的时间,则我们可以算出完成整个工程需要的最短时间。在这些子任务中,有些任务即使推迟几天完成,也不会影响全局的工期;但是有些任务必须准时完成,否则整个项目的工期就要因此延误,这种任务就叫“关键活动”。

请编写程序判定一个给定的工程项目的任务调度是否可行;如果该调度方案可行,则计算完成整个工程项目需要的最短时间,并输出所有的关键活动。

输入格式:

输入第1行给出两个正整数N(≤100)和M,其中N是任务交接点(即衔接相互依赖的两个子任务的节点,例如:若任务2要在任务1完成后才开始,则两任务之间必有一个交接点)的数量。交接点按1~N编号,M是子任务的数量,依次编号为1~M。随后M行,每行给出了3个正整数,分别是该任务开始和完成涉及的交接点编号以及该任务所需的时间,整数间用空格分隔。

输出格式:

如果任务调度不可行,则输出0;否则第1行输出完成整个工程项目需要的时间,第2行开始输出所有关键活动,每个关键活动占一行,按格式“V->W”输出,其中V和W为该任务开始和完成涉及的交接点编号。关键活动输出的顺序规则是:任务开始的交接点编号小者优先,起点编号相同时,与输入时任务的顺序相反。

输入样例:

7 8
1 2 
### 关于 PTA 平台上的数据结构考题——顺序表插入操作 在 PTA 平台上,涉及 **顺序表插入操作** 的题目通常会考察学生对于线性表基本操作的理解和实现能力。以下是针对此类问题的一个典型示例及其解析。 #### 题目描述 假设有一个顺序表 `L`,其元素由用户输入并以 `-1` 结束(注意:`-1` 不属于顺序表的元素)。现在需要实现在指定位置 `pos` 处插入一个新的元素 `val`。如果插入成功,则返回更新后的顺序表;否则提示错误信息。 --- #### 输入输出说明 - **输入**: 第一行是一个以 `-1` 结束的顺序表示列(最多包含 100 个正整数),所有数据间用空格分隔[^1]。第二行为两个整数 `pos` 和 `val`,分别表示要插入的位置索引以及待插入的新值。 - **输出**: 如果插入成功,则打印更新后的顺序列表;如果失败(如超出范围或其他非法情况),则输出 `"Error"`。 --- #### 示例代码实现 以下提供了一个基于 C++ 实现的解决方案: ```cpp #include <iostream> using namespace std; const int MAX_SIZE = 100; // 定义最大容量 void insertElement(int L[], int &n, int pos, int val) { if (n >= MAX_SIZE || pos < 0 || pos > n) { // 判断合法性 cout << "Error" << endl; return; } // 后移元素为新元素腾出空间 for (int i = n; i > pos; --i) { L[i] = L[i - 1]; } L[pos] = val; // 插入目标值 ++n; // 更新长度 } int main() { int L[MAX_SIZE], temp, n = 0, pos, val; // 输入原始顺序表 while (cin >> temp && temp != -1) { if (n < MAX_SIZE) { L[n++] = temp; } } cin >> pos >> val; // 获取插入位置和值 // 执行插入操作 insertElement(L, n, pos, val); // 输出结果 if (n <= MAX_SIZE) { for (int i = 0; i < n; ++i) { cout << L[i] << (i < n - 1 ? " " : "\n"); } } return 0; } ``` --- #### 代码逻辑分析 上述代码实现了如下功能: 1. 初始化一个固定大小的最大数组来存储顺序表的数据,并通过循环读取直到遇到特殊标记 `-1` 来终止输入过程。 2. 提供了一个辅助函数用于执行实际的插入动作,在此过程中考虑了边界条件检查,比如当尝试向不存在的位置或者已满容器中添加项时应如何处理。 3. 主函数部分负责接收用户的指令参数即具体想放置在哪一位以及对应的数值是多少之后调用了前面定义好的方法完成整个流程控制[^3]。 --- #### 注意事项 需要注意的是,这里的例子仅作为教学用途展示了一种可能解法思路并非唯一正确答案形式。另外还需强调一点就是关于异常状况下的反馈机制设置得越完善越好以便提高用户体验满意度同时减少潜在风险发生概率。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值