【拓扑排序】【DG特长生2017】工程
发布日期:2021-05-07 22:47:28 浏览次数:16 分类:精选文章

本文共 2455 字,大约阅读时间需要 8 分钟。

为了解决这个问题,我们需要找到完成所有任务的最短时间,考虑任务之间的依赖关系和允许并行执行多个任务。

方法思路

  • 构建依赖图:将任务和它们的依赖关系表示为有向图。
  • 拓扑排序:确定任务的执行顺序,确保每个任务在其所有依赖完成后才能执行。
  • 动态规划计算完成时间:对于每个任务,计算其最早可以开始的时间,即所有前驱任务完成时间的最大值加上其本身的完成时间。
  • 处理并发任务:使用队列来管理可以立即执行的任务,动态地处理任务之间的依赖关系,确保尽可能多的任务同时进行。
  • 解决代码

    题目大意

    有一系列项目,每个项目都有一个完成时间。某些任务必须在其他特定任务完成之后才能开始。我们的目标是找到完成所有任务的最短时间,允许同时执行多个可以被执行的任务。


    解题思路

    我们需要解决的主要问题是如何高效地安排任务执行顺序,考虑任务的依赖关系并最大化并行执行的效率。具体步骤如下:

    1. 构建依赖图:将每个任务及其依赖关系表示为有向图。例如,如果任务B必须在任务A之后才能执行,则在图中添加一条从A指向B的边。
    2. 拓扑排序:生成任务的执行顺序,确保每个任务在其所有前驱任务完成之后才能被执行。这可以通过深度优先搜索或广度优先搜索实现。
    3. 计算完成时间:使用动态规划的方法,记录每个任务的最早开始时间。对于每个任务i,其最早开始时间等于其所有前驱任务完成时间的最大值加上它自身的完成时间ti[i]。这样可以确保所有依赖都被满足,并且尽可能地优化整个项目的总时间。
    4. 处理并发执行:由于允许多个任务同时执行,只要它们没有相互依赖。因此,在计算每个任务的最早开始时间时,需要考虑当前时间点已经完成的所有可以执行的任务。使用优先队列可以有效地管理这些并发执行的任务,确保任务的高效执行。

    代码实现

    #include
    #include
    #include
    using namespace std;
    struct Edge {
    int to;
    int next;
    };
    int main() {
    int n, ti[100], pd[100];
    vector
    in_degree[100];
    vector
    > adjacency[100]; queue
    q; vector
    earliest_start[100]; vector
    earliest_end[100]; vector
    visited[100]; // 读取输入 cin >> n; for(int i=1; i<=n; ++i) { cin >> ti[i]; } // 构建依赖图 for(int i=1; i<=n; ++i) { for(int j=1; j<=n; ++j) { if(i != j) { pd[j] = i; in_degree[j] += 1; adjacency[i].push_back(j); } } } // 初始化队列和时间 for(int i=1; i<=n; ++i) { if(in_degree[i] == 0) { q.push(i); earliest_start[i] = 0; earliest_end[i] = ti[i]; } } // 处理队列 while(!q.empty()) { int u = q.front(); q.pop(); visited[u] = true; for(int v : adjacency[u]) { in_degree[v] -= 1; if(in_degree[v] == 0) { earliest_start[v] = max(earliest_start[v], earliest_end[u] + ti[v]); earliest_end[v] = earliest_start[v] + ti[v]; q.push(v); } else { earliest_start[v] = max(earliest_start[v], earliest_end[u] + ti[v]); } } } // 检查是否所有任务都被处理 if(n == 0) { cout << 0 << endl; } else if(visited[n-1]) { int max_time = earliest_end[n]; for(int i=1; i<=n; ++i) { if(earliest_end[i] > max_time) { max_time = earliest_end[i]; } } cout << max_time << endl; } else { cout << -1 << endl; } return 0; }

    总结

    通过构建任务依赖图并使用拓扑排序,我们能够确定任务的执行顺序。动态规划的方法用于计算每个任务的最早开始时间,从而确定最短完成时间。代码实现中,队列用于管理并发执行的任务,确保依赖关系得到满足。最终,我们可以通过检查所有任务的完成时间来确定最短完成时间。

    上一篇:【区间DP】【DG特长生2017】T4摆渡线路
    下一篇:【DFS】【DP】【DG特长生2017】T2益智游戏

    发表评论

    最新留言

    逛到本站,mark一下
    [***.202.152.39]2025年04月10日 01时06分49秒