大量输入导致拓扑排序崩溃

时间:2018-08-27 08:25:24

标签: python python-3.x algorithm runtime-error graph-theory

问题:-

现在您可以在Berland州立大学接受在线课程! Polycarp需要通过其专业的k个主要在线课程来获得文凭。总共有n门课程可供通过。

在线课程的依赖性使情况变得复杂,对于每门课程,都有一个在开始本在线课程之前必须通过的列表(列表可以为空,这意味着没有限制)。

帮助Polycarp通过总数最少的课程以获得专业(这意味着通过所有主要和必要的课程)。编写一个打印课程顺序的程序。

Polycarp始终如一地通过课程,完成上一门课程后,他便开始下一门课程。每门课程都不能超过一次。

输入:-

第一行包含n和k(1≤k≤n≤105)—在线课程的数量和Polycarp专业的主要课程的数量。

第二行包含从1到n的k个不同整数-Polycarp专业的主要在线课程的数量。

然后是n行,每行描述了下一条路线:第i行对应于路线i。每行从整数ti(0≤ti≤n-1)-第i个所依赖的路线数开始。然后是从1到n的ti个不同整数的序列-随机顺序的进程数,第i个依赖于此。可以保证没有路线可以依靠自己。

保证所有值ti的总和不超过10 ^ 5。

输出:-

如果不可能,-1

如果可能,然后打印他需要参加的课程数量,然后打印他参加课程的顺序

带注释的代码:-

import sys
flag=True
sys.setrecursionlimit(2000000)
c=[];st=[];
def topo(s):#Traversing the array and storing the vertices
    global c,st,flag;
    c[s]=1; #Being Visited
    for i in adjli[s]:#visiting neighbors
        if c[i]==0:
            topo(i)
        if c[i]==1:
            flag=False# If Back Edge , Then Not Possible
    st.append(str(s))
    c[s]=2 # Visited

try:
    n,k=map(int,input().split(' '))#Number Of Courses,Dependencies
    main=list(map(int,input().split(' ')))#Main Dependencies
    depen=[]#Dependencies List
    for i in range(n):
        depen.append(list(map(int,input().split(' ')))[1:]);c.append(0)#Append Input To Dependencies List, Marking Visited as 0(False)
    c.append(0)
    adjli=[]
    adjli.append(main)#Assuming Main Course at index 0 with dependencies as Main Dependency(main)
    for i in range(len(depen)):
        adjli.append(depen[i])#Appending Other Dependencies
    topo(0)#TopoLogical Sort Order
    st.pop(-1)#popping the assumed Main Couse
    if flag:# IF possible then print
        print(len(st))
        print(' '.join(st))
    else:
        print(-1)
except Exception as e:
    print(e,"error")

我做了什么?

我进行了拓扑排序并存储了遍历顺序。我假设专业课程存储在索引0中,并相应地形成了图形。如果遇到BackEdge,我返回-1。

出什么问题了?

代码为小输入提供了正确的输出,但是在大输入(例如:-

)的情况下遇到了运行时错误

生成输入的代码:-

print(100000,1)
print(100000)
for i in range(100000):
  if i==0:
    print(i)
  else:
    print(1,i)

我该如何解决这个问题?

我试图打印运行时错误,但是什么也没显示。

链接到问题:-Question

我的解决方案:-Solution

1 个答案:

答案 0 :(得分:1)

在递归过程中堆栈有问题。即使明确声明了此限制,Python的递归限制较低。此codeforce博客中提到了此问题:https://codeforces.com/blog/entry/45135/

一种解决方案是使用迭代方法而不是递归方法来实现功能拓扑。

更改的代码可以是:

import sys
flag=True
sys.setrecursionlimit(2000000000)
c=[];st=[];
cur_adj=[]
def topo(s):#Traversing the array and storing the vertices
    global c,st,flag;
    stack = [s]
    while(stack):
        s = stack[-1]
        c[s]=1; #Being Visited
        if(cur_adj[s] < len(adjli[s])):
            cur = adjli[s][cur_adj[s]]
            if(c[cur]==0):
                stack.append(cur)
            if(c[cur]==1):
                flag=False# If Back Edge , Then Not Possible
            cur_adj[s]+=1
        else:
            c[s]=2
            st.append(str(s))
            del stack[-1]

try:
    n,k=map(int,input().split(' '))
    main=list(map(int,input().split(' ')))
    depen=[]
    for i in range(n):
        depen.append(list(map(int,input().split(' ')))[1:]);c.append(0)
        cur_adj.append(0)
    c.append(0)
    cur_adj.append(0)
    adjli=[]
    adjli.append(main)#Assuming Main Course at index 0 with dependencies as Main Dependency(main)
    for i in range(len(depen)):
        adjli.append(depen[i])#Appending Other Dependencies
    topo(0)#TopoLogical Sort Order
    st.pop(-1)#popping the assumed Main Couse
    if flag:# IF possible then print
        print(len(st))
        print(' '.join(st))
    else:
        print(-1)
except Exception as e:
    print(e,"error")

此代码实现了递归期间堆栈的作用。 cur_adj是一个列表,其中cur_adj [i]保存i的下一个要访问的相邻节点的索引。一旦访问完所有i的相邻节点,我就会从堆栈中弹出(堆栈是模拟递归堆栈的普通列表)。