利用Topological sorting判断可并行程序的最短时间

链接:https://leetcode-cn.com/problems/parallel-courses/solution/ping-xing-ke-cheng-by-leetcode-solution/
题目来源:力扣(LeetCode)

拓扑排序中最前面的节点,该节点一定不会有任何入边,也就是它没有任何的先修课程要求。当我们将一个节点加入答案中后,我们就可以移除它的所有出边,代表着它的相邻节点少了一门先修课程的要求。如果某个相邻节点变成了「没有任何入边的节点」,那么就代表着这门课可以开始学习了。按照这样的流程,我们不断地将没有入边的节点加入答案,直到答案中包含所有的节点(得到了一种拓扑排序)或者不存在没有入边的节点(图中包含环)。

算法

我们使用一个队列来进行广度优先搜索。开始时,所有入度为 0 的节点都被放入队列中,它们就是可以作为拓扑排序最前面的节点,并且它们之间的相对顺序是无关紧要的。

在广度优先搜索的每一步中,我们取出队首的节点 u:

我们将 u 放入答案中;

我们移除 u 的所有出边,也就是将 u 的所有相邻节点的入度减少 1。如果某个相邻节点 v 的入度变为 0,那么我们就将 v 放入队列中。

在广度优先搜索的过程结束后。如果答案中包含了这 n 个节点,那么我们就找到了一种拓扑排序,否则说明图中存在环,也就不存在拓扑排序了。

#存储每个节点的入度(0~n-1)
        precourse_cnt = [0]*n
        # 存储有向图
        dic = collections.defaultdict(list)
        for edge in relations:
            dic[edge[0]].append(edge[1])
            precourse_cnt[edge[1]-1]+=1
        # 将所有入度为 0 的节点放入队列中(1~n)
        queue=[course for course in range(1,n+1) if precourse_cnt[course-1]==0]
        term = 0#判断有多少段并行课程的时间段才能上完所有的课
        while queue:
            next_semester = []#1~n
            #搞定queue中所有入度为0的课程
            for cur_course in queue:
                for neigh in dic[cur_course]:
                    #neigh入度(0~n-1)减去1
                    precourse_cnt[neigh-1]-=1
                    if precourse_cnt[neigh-1]==0:
                        next_semester.append(neigh)
            #queue中为所有新的入度为0的课程
            queue = next_semester
            term+=1
        #check whether cycle exists
        #存储每个节点的入度为0才有topologial order,否则存在cycle
        if sum(precourse_cnt)!=0:
            return -1
        return term

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值