📜  门| GATE-CS-2005 |第 50 题(1)

📅  最后修改于: 2023-12-03 15:28:42.402000             🧑  作者: Mango

门 | GATE-CS-2005 | 第50题

这是一道GATE-CS-2005中的题目,题号为50。这道题涉及到了图论中关于有向图的拓扑排序的概念,以及使用队列进行实现。

题目描述:

给定一个带权重值的有向无环图,其中每个顶点代表一个项目,每条有向边代表一个项目之间的依赖关系,权重代表执行该项目所需的时间。现在,需要找到一个执行顺序,使得每个项目都能在其前面的项目执行完毕之后才能开始执行,并且能够使得总执行时间最少。假设每个项目仅能被执行一次。

输入格式:

输入包括多组数据,每组数据包括整数n和m(1<=n<=10000,0<=m<=100000),表示项目数和依赖关系数。接下来m行,每行包括三个整数u、v、w(1<=u,v<=n,1<=w<=1000),表示建立从u到v的有向边,权重为w。

输出格式:

对于每组数据,输出一个整数,代表所需的最短执行时间。

算法思路:

本题属于有向无环图(Directed Acyclic Graph, DAG)的拓扑排序问题,同时又涉及到了对DAG中边权重的考虑。我们可以使用一个队列来进行拓扑排序过程,并使用一个数组记录每个顶点的入度,以及一个dp数组记录每个项目的最短执行时间。

具体算法如下:

  1. 对输入的邻接表建图,并初始化数组indegree[i]=0和dp[i]=0。
  2. 对所有边进行扫描,统计每个节点的入度indegree[]。
  3. 将入度为零的点加入队列Q。
  4. 取出队首元素,依次扫描该节点的所有出边,并更新每个出边对应节点的dp值(最短执行时间)。同时将所有出边对应节点的入度indegree--,如果入度为零,将该节点加入队列Q。
  5. 重复步骤4直至队列为空。
  6. dp数组中的最大值即为所需的最短执行时间。

代码实现:

```python
from queue import Queue

def topological_sort(n, m, adj):
    indegree = [0] * (n+1) # 入度数组
    dp = [0] * (n+1) # 每个项目的最短执行时间
    Q = Queue()
    for i in range(1, n+1):
        for j in adj[i]:
            indegree[j] += 1 # 统计入度
    for i in range(1, n+1):
        if indegree[i] == 0:
            Q.put(i) # 将入度为0的节点入队
            dp[i] = 0
    while not Q.empty():
        u = Q.get()
        for v, w in adj[u]:
            indegree[v] -= 1
            dp[v] = max(dp[v], dp[u]+w) # 更新最短执行时间
            if indegree[v] == 0:
                Q.put(v) # 入度为0时将节点入队
    return max(dp) # 所需最短执行时间为dp中最大值

n, m = map(int, input().split())
adj = [[] for _ in range(n+1)] # 邻接表
for i in range(m):
    u, v, w = map(int, input().split())
    adj[u].append((v, w)) # 加入边
print(topological_sort(n, m, adj))

间接置空,防粘

总结:

本题提供了一个使用队列进行拓扑排序的具体实现方法,同时还涉及到了边权重的处理问题。这种使用队列进行拓扑排序的方法的时间复杂度为O(n+m),空间复杂度为O(n+m),因此可适用于时间要求紧、数据规模较小的场合。