'How to speed up this Python DFS search with DP?

I have the following code, which works correctly, but which runs too long on large numbers of input. I thought I had optimized it pretty well, but I can't figure out what to do next to improve runtime for large input sets.

The goal (from CodeSignal) is to check at every time interval and see if we can start a new task, based on whether or not its precedent tasks have finished - and then return an array of the tasks with their start times.

def dfs(node, adj, dp, vis):
    vis[node] = True
    for i in range(0, len(adj[node])): 
        if not vis[adj[node][i]]:
            dfs(adj[node][i], adj, dp, vis)
        dp[node] = max(dp[node], 1 + dp[adj[node][i]])
   
def addEdge(adj, u, v):
    adj[u].append(v)
   
def findLongestPath(adj, n):
    global dp
    dp = [0] * (n + 1)
    vis = [False] * (n + 1)
    for i in range(1, n + 1): 
        if not vis[i]:
            dfs(i, adj, dp, vis)

def solution(quota,inputs,duration):
    n=len(inputs)
    adj=[[] for i in range(n + 1)]
    for i in range(n):
        p=inputs[i]
        for j in range(len(p)):
            addEdge(adj,p[j],i)
    findLongestPath(adj,n)
    done=0
    moment=0
    einterval=1
    result=[-1]*(n)
    status=[-1]*(n)
    elapsed=[-1]*(n)
    quotaused=0
    nextmoment=float('inf')
    dpmap=[]
    for i in range(n):
        dpmap.append([])
    mmoments=[float('inf')]*(n)
    for i in range(len(dpmap)):
        dpmap[i]=[]
    for t in range(len(dp)-1):
        index=dp[t]
        dpmap[index].append(t)
    while (done==0):
        done=1
        nextmoment=float('inf')
        for i in range(n):
            if (elapsed[i]>=0):
                elapsed[i]=elapsed[i]+einterval
            if (elapsed[i]==duration[i]):
                status[i]=2
                mmoments[i]=float('inf')
                quotaused=quotaused -1
        for i in range(n):
            if (status[i]==-1):
                ready=1
                for t in range(len(inputs[i])):
                    task=inputs[i][t]
                    if (status[task]<2):
                        ready=0
                        break
                if (ready==1):
                    status[i]=0
        for l in range(len(dpmap)-1,-1,-1):
            if (quotaused==quota):
                break
            for t in range(len(dpmap[l])):
                task=dpmap[l][t]
                if (status[task]==0):
                    status[task]=1
                    elapsed[task]=0
                    quotaused=quotaused +1
                    result[task]=moment
                    mmoments[task]=moment+duration[task]
                    done=0
                    if (quotaused==quota):
                        break
        for i in range(n):
            nextmoment=min(nextmoment,mmoments[i])
        einterval=nextmoment-moment
        moment=nextmoment

        if (done==1):
            for i in range(n):
                if (result[i]==-1):
                    done=0
                    break
    return result


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source