Parallel Courses III

本文介绍了一种利用图论和拓扑排序的方法,解决给定课程依赖关系和完成时间的最短完成路径问题。通过分析prerequisites和time数组,计算并返回完成所有课程所需的最小月数。核心在于利用finishTime数组更新节点完成时间,并确保同时进行课程的数量限制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

You are given an integer n, which indicates that there are n courses labeled from 1 to n. You are also given a 2D integer array relations where relations[j] = [prevCoursej, nextCoursej] denotes that course prevCoursej has to be completed before course nextCoursej (prerequisite relationship). Furthermore, you are given a 0-indexed integer array time where time[i] denotes how many months it takes to complete the (i+1)th course.

You must find the minimum number of months needed to complete all the courses following these rules:

  • You may start taking a course at any time if the prerequisites are met.
  • Any number of courses can be taken at the same time.

Return the minimum number of months needed to complete all the courses.

Note: The test cases are generated such that it is possible to complete every course (i.e., the graph is a directed acyclic graph).

Example 1:

Input: n = 3, relations = [[1,3],[2,3]], time = [3,2,5]
Output: 8
Explanation: The figure above represents the given graph and the time required to complete each course. 
We start course 1 and course 2 simultaneously at month 0.
Course 1 takes 3 months and course 2 takes 2 months to complete respectively.
Thus, the earliest time we can start course 3 is at month 3, and the total time required is 3 + 5 = 8 months.

思路:就是个topo排序,注意的点:

1. 给的relationship是index +1的,所以为了方便,build graph的时候,直接减去1,这样和后面的time也 一一对应;

2. 核心的算法就是用topo更新每个点index,需要花的时间,最后求个最大的即可。

3. 计算neighbor的时间,finishTime[neighbor] = finishTime[node] + time[neighbor]; 因为node poll出来就是入度为0点,那么就应该用finishTime来计算;

class Solution {
    public int minimumTime(int n, int[][] relations, int[] time) {
        int[] finishTime = new int[n];
        int[] indegree = new int[n];
        HashMap<Integer, List<Integer>> graph = new HashMap<>();
        for(int i = 0; i < n; i++) {
            graph.putIfAbsent(i, new ArrayList<>());
        }
        for(int[] relation: relations) {
            // a -> b;
            int a = relation[0] - 1;
            int b = relation[1] - 1;
            graph.get(a).add(b);
            indegree[b]++;
        }
        
        Queue<Integer> queue = new LinkedList<>();
        for(int i = 0; i < n; i++) {
            if(indegree[i] == 0) {
                finishTime[i] = time[i];
                queue.offer(i);
            }
        }
        
        while(!queue.isEmpty()) {
            Integer node = queue.poll();
            for(Integer neighbor: graph.get(node)) {
                // 注意这里,因为node 已经poll出来了,所以计算的时候是用的finishTime[node] + time[neighbor];
                finishTime[neighbor] = Math.max(finishTime[neighbor], finishTime[node] + time[neighbor]);
                indegree[neighbor]--;
                if(indegree[neighbor] == 0) {
                    queue.offer(neighbor);
                }
            }
        }
        
        int res = 0;
        for(int i = 0; i < n; i++) {
            res = Math.max(res, finishTime[i]);
        }
        return res;
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值