📜  门| GATE CS 2019 |第 40 题(1)

📅  最后修改于: 2023-12-03 14:58:20.313000             🧑  作者: Mango

介绍

这是一道关于图的题目,涉及到图的遍历和最短路径算法。具体来说,给定一个有向无环图(DAG),每个节点代表一个任务,每个任务都有一个时间和一个价值。任务之间存在依赖关系,即一个任务只有在其依赖的任务完成后才能开始。要求在不超时的情况下完成任务并获得最大的总价值。

这道题的基本思路是先对图进行拓扑排序,然后依次遍历拓扑序列中的每个节点。在遍历某个节点时,先更新其前驱节点的最早完成时间(即最长路径),再更新自己的最早完成时间和最大价值。最后得到最后一个节点的最早完成时间即为所求的总时间,得到最后一个节点的最大价值即为所求的总价值。

思路

  1. 对图进行拓扑排序

    拓扑排序可以用 Kahmam算法 实现,具体可参考 Kahman算法 - 维基百科,自由的百科全书 (wikipedia.org)

  2. 遍历拓扑序列中的每个节点,更新其最长路径和最大价值

    • 初始化所有节点的最早完成时间为 0,最大价值为节点本身的价值
    • 遍历一个节点时,遍历其所有前驱节点
      • 更新其前驱节点的最早完成时间(即最长路径)
      • 更新自己的最早完成时间和最大价值
    • 遍历完所有节点后,所求的总时间即为最后一个节点的最早完成时间,总价值即为最后一个节点的最大价值。

代码片段

下面是关键部分的Python代码片段,其中graph是有向无环图的邻接表表示,times是每个任务的时间,values是每个任务的价值:

def dynamic_programming(graph, times, values):
    # 拓扑排序
    sorted_nodes = topological_sort(graph)
    
    # 初始化最早完成时间和最大价值
    earliest_times = [0] * len(graph)
    max_values = values.copy()

    # 利用拓扑序列遍历每个节点
    for node in sorted_nodes:
        # 遍历前驱节点,更新最长路径
        for predecessor in graph[node]:
            earliest_times[node] = max(earliest_times[node], earliest_times[predecessor] + times[predecessor])
        
        # 更新最早完成时间和最大价值
        earliest_times[node] += times[node]
        max_values[node] += max_values[predecessor]

    # 返回最后一个节点的最早完成时间和最大价值
    return earliest_times[-1], max_values[-1]

以上是本题的思路和核心代码,可供程序员参考。