Project Manager | Practice | GeeksforGeeks

An IT company is working on a large project. The project is broken into N modules and distributed to different teams. Each team can work parallelly. The amount of time (in months) required to complete each module is given in an array duration[ ] i.e. time needed to complete ith module is duration[i] months. 
You are also given M dependencies such that for each i (1 ≤ i ≤ M)  dependencies[i][1]th module can be started after dependencies[i][0]th module is completed.
As the project manager, compute the minimum time required to complete the project.
Note: It is guaranteed that a module is not dependent on itself.
Example 1:
Input:
N = 6, M = 6
duration[] = {1, 2, 3, 1, 3, 2}
dependencies[][]:
[[5, 2]
 [5, 0]
 [4, 0] 
 [4, 1]
 [2, 3]
 [3, 1]]
Output: 
8
Explanation: 

The Graph of dependency forms this and 
the project will be completed when Module 
1 is completed which takes 8 months.

Example 2:
Input:
N = 3, M = 3
duration[] = {5, 5, 5}
dependencies[][]:
[[0, 1]
 [1, 2]
 [2, 0]]
Output: 
-1
Explanation: 
There is a cycle in the dependency graph 
hence the project cannot be completed.

Your Task:
Complete the function minTime() which takes N, M, duration array, and dependencies array as input parameter and return the minimum time required. return -1 if the project can not be completed. 
Expected Time Complexity: O(N+M)
Expected Auxiliary Space: O(N)
Constraints:
1 ≤ N ≤ 105
0 ≤ M ≤ 2*105
1 ≤ duration[i] ≤ 105
0 ≤ dependencies[i][j] < N
0
aliaksandrhn2 months ago
class Solution {
    public int minTime(ArrayList<pair> dependency, int[] duration, int n, int m) {
        int max = 0, tasks = 0;
        for(int num: duration) max = Math.max(max, num);
        Map<Integer, List<Integer>> map = new HashMap<>();
        int[] inDegree = new int[n], time = new int[n];
        for(pair p: dependency) {
            map.putIfAbsent(p.x, new ArrayList<>());
            map.get(p.x).add(p.y);
            inDegree[p.y] ++ ;
        }
        Queue<Integer> que = new LinkedList<>();
        for(int i = 0; i < n; i ++) {
            if(inDegree[i] == 0) {
                que.add(i);
                time[i] = duration[i];
            }
        }
        while(!que.isEmpty()) {
            int cur = que.poll();
            tasks ++ ;
            if(!map.containsKey(cur)) continue;
            List<Integer> l = map.get(cur);
            for(int next: l) {
                if(--inDegree[next] == 0) 
                    que.add(next);
                time[next] = Math.max(time[next], time[cur] + duration[next]);
                max = Math.max(max, time[next]);
            }
        }
        return tasks < n ? -1 : max;
    }
}
0
aliaksandrhn2 months ago
How is the answer in Example 1 8? In order to complete task 1, we need to complete 5→2→3→1 which is: 5→2 1 month, 2→3 3 months, 3→1 2 months, so 1 + 3 + 2 = 6. How did they get 8?
0
triple2double13 months ago
JUST 3 LINE CHANGE IN TYPICAL TOPOSORT
I feel so dumb for not able to solve this “79% accuracy rate question”.
 
The answer to first question in not 6 ,don't do that mistake , take luck against you ,you can do module 1 in 5 and 8 months , but if someone asks you for guarantee ,you won't say 5. 
you just need to find the max(min time to complete each module) ,where the min time to complete module i is max(all ways you can do that module following the dependencies)
 
class Solution{
    public:
    int minTime(vector<pair<int, int>> &dedency, int dur[], int n, int m) {
        vector<vector<int>> adj_list(n);
        vector<int>mt_of_modules(dur,dur+n);
        vector<int>topo_sort;
        
        vector<int>in(n,0);
        for(auto &d:dedency){
            adj_list[d.first].push_back(d.second);
            in[d.second]++;
        }
        
        queue<int>q;
        for(int i=0;i<n;i++){
            if(in[i]==0)
                q.push(i);
        }
        
    
        while(q.size()!=0)
        {
            auto f=q.front();q.pop();
            topo_sort.push_back(f);
            for(auto nbr:adj_list[f]){
                in[nbr]--;
                if(in[nbr]==0){
                    q.push(nbr);
                }
            }
        }
        if(topo_sort.size()!=n)
            return -1;
        
        for(auto ts:topo_sort)
        { 
            for(auto nbr:adj_list[ts]){
                mt_of_modules[nbr]=max(mt_of_modules[nbr], mt_of_modules[ts]+dur[nbr]);
            }
        }
        return *max_element(mt_of_modules.begin(),mt_of_modules.end());
    
    }
};
 
0
ghazanferwahab26 months ago
can someone give solution in java??
0
rohit_iiitl7 months ago
 
dp[i] = min time required to complete ith task.
 
Algorithm:Firstly assign dp[i] to duration[i], as it is min time required to perform that task. Now, lets say task B is dependent on A, then time reqd for B will be time of A + time of B (as A needs to be performed before B) (dp[B] = dp[A] + dp[B]). Now lets say B is also dependent on C, and C and A are independent. For this case dp[B] = dp[C] + dp[B], but this this will not solve our problem, as we are ignoring A. Therefore, dp[B] = max(dp[A] + dp[B], dp[C] + dp[B]), as if A takes more time than C, then we need to wait for A to complete before performing task B. i.e; calculating max of both. We are taking maximum of it, but actually dp[B] is minimum time required to complete task B (waiting for both A and C before doing B). Use kahn's algorithm to solve for all dependency.
 
At last for every i, dp[i] will contain minimum time required to complete that particular task. Hence if we find max of this array. Then it will be minimum time required for whole process (to complete all tasks), as other tasks can run parallelly and complete before that max time.
 
In solution denoting dp[ ] as timeReqd[ ]
 
int minTime(vector<pair<int, int>> &dependency, int duration[], int n, int m) {
    vector<int> indegree(n, 0), timeReqd(n, 0), adj[n];
    queue<int> q;
    for(int i=0; i<m; i++) {
        indegree[dependency[i].second]++;
        adj[dependency[i].first].push_back(dependency[i].second);
    }
    for(int i=0; i<n; i++) {
        if(indegree[i] == 0)
            q.push(i), timeReqd[i]=duration[i];
    }
    int numNodes=0;
    while(!q.empty()) {
        int front = q.front();
        q.pop();
        numNodes++;
        for(auto v:adj[front]) {
            timeReqd[v] = max(timeReqd[v], timeReqd[front]+duration[v]);
            if(--indegree[v] == 0) q.push(v);
        }
    }
    if(numNodes != n) return -1;
    return *max_element(timeReqd.begin(), timeReqd.end());
}
+1
anutiger7 months ago
    public:
    struct Node{
        int node;
        int val;
        int price;
        Node(int x,int y){
            node = x;
            val = y;
            price = 0;
        }
    }; 
    int minTime(vector<pair<int, int>> &dep, int dur[], int n, int m) {
    vector<int> vis(n , 1);
    vector<int> adj[n];
    vector<int> cnt(n , 0);
    vector<Node*> tmp;
    for(int i = 0 ; i < n ; i ++){
        Node *temp = new Node(i,dur[i]);
        tmp.push_back(temp);
    }
    for(int i = 0 ; i < m ; i ++){
        int x = dep[i].first;
        int y = dep[i].second;
        adj[x].push_back(y);
        cnt[y]++;
    }
    queue<Node*>pq;
    while(true){
        if(pq.empty()){
            int flag = 1;
                for(int i = 0; i  < n ; i ++){
                    if(cnt[i] == 0){
                        pq.push(tmp[i]);
                        cnt[i] = -1;
                        flag = 0;
                    }
                }
                if(flag)
                    break;
        }
        int size = pq.size();
        for(int i = 0; i < size; i ++){
            auto it = pq.front();pq.pop();
            int price = it->val + it->price;
            if(adj[it->node].size() == 0){
                tmp[it->node]->price += tmp[it->node]->val;
                continue;
            }
            for(int j : adj[it->node]){
                auto t = tmp[j];
                if(t->price < price){
                    t->price = max(t->price,price);
                }
                cnt[j]--;
            }
        }
    }
    for(int i = 0; i < n ; i ++){
        if(cnt[i] > 0)
            return -1;
    }
    int res = 0;
    for(int i = 0 ; i < n ; i ++){
        res = max(res,tmp[i]->price);
    }
    if(res == 0) return -1;
    return res;
    }
+1
sunnysaraff7 months ago
int minTime(vector<pair<int, int>> &dependency, int duration[], int n, int m) {
        vector<int> adj[n],in(n),dist(n,INT_MIN);
        vector<bool> vis(n,false),rec(n,false);
        for(auto& edge:dependency){
            adj[edge.first].push_back(edge.second);
            in[edge.second]++;
        }
        
        queue<int> q;
        for(int i=0;i<n;i++){
            if(!in[i]){
                dist[i] = duration[i];
                q.push(i);
            }
        }
        
        int cnt = 0;
        while(!q.empty()){
            int v = q.front();
            q.pop();
            
            cnt++;
            
            for(auto& u:adj[v]){
                in[u]--;
                dist[u] = max(dist[u],dist[v]);
                if(!in[u]){
                    dist[u] += duration[u];
                    q.push(u);
                }
            }
        }
        
        return (cnt==n)?*max_element(dist.begin(),dist.end()):-1;
        
    }
+3
geminicode7 months ago
Hi can anyone explain why the answer of example-1 is 8 and not 9?
 
0
rishug7707 months ago
#Python Solution. Topological Sorting and a touch of dynamic programming
indeg=[0]*n       ans=[]       q=[]       dp=[]       adj=[]       for i in range(n):           adj.append([])           dp.append(duration[i])                  for i in range(m):           indeg[dependency[i][1]]+=1           adj[dependency[i][0]].append(dependency[i][1])       for i in range(n):           if(indeg[i]==0):               q.append(i)       while(q):           a=q.pop(0)           ans.append(a)           for i in adj[a]:               dp[i]=max(dp[i],duration[i]+dp[a])               indeg[i]-=1               if(indeg[i]==0):                   q.append(i)                          if(len(ans)!=n):           return -1       return max(dp)
+4
mastermind_7 months ago
(C++) Topological Sorting( Kahn's Algorithm ) + DP Solution, ~ Fastest  ~  0.0 s  ~ O(M+N) 
int minTime(vector<pair<int, int>> &d, int dur[], int n, int m) {
	vector<int> indeg(n, 0), topo, dp(n, 0), adj[n];
	queue<int> q;
	for(int i=0;i<m;i++)indeg[d[i].second]++,adj[d[i].first].push_back(d[i].second);
	for (int i = 0; i < n; i++)if (indeg[i] == 0)q.push(i), dp[i] = dur[i];
	while (!q.empty()) {
		auto x = q.front(); q.pop();
		topo.push_back(x);
		for (auto v : adj[x]) {
			dp[v] = max(dp[v], dur[v] + dp[x]);
			if (--indeg[v]==0)q.push(v);
		}
	}
	if (topo.size() != n)return -1; // contains cycle !!!
	return *max_element(dp.begin(), dp.end());
}
We strongly recommend solving this problem on your own before viewing its editorial. Do you still
                    want to view the editorial?
 Login to access your submissions. 

Problem


Contest

Reset the IDE using the second button on the top right corner.
Avoid using static/global variables in your code as your code is tested against multiple test cases and these tend to retain their previous values.
Passing the Sample/Custom Test cases does not guarantee the correctness of code. On submission, your code is tested against multiple test cases consisting of all possible corner cases and stress constraints.
You can access the hints to get an idea about what is expected of you as well as the final solution code.
You can view the solutions submitted by other users from the submission tab.