Python中的Kruskal算法

时间:2018-07-30 06:01:21

标签: python-3.x algorithm greedy kruskals-algorithm

import heapq
from collections import defaultdict

a = list(map(int, input().split()))

nodes = a[0]
disjoint_set = [-1]*(nodes+1)
rank_set = [0]*(nodes+1)
edges = a[1]
heap = []

def get_parent(u):
    if disjoint_set[u] == -1:
        return u
    return get_parent(disjoint_set[u])

def make_union(x, y):
    x_parent = get_parent(x)
    y_parent = get_parent(y)
    if rank_set[x_parent] == rank_set[y_parent]:
        disjoint_set[x_parent] = y_parent
        rank_set[x_parent] +=1
    elif rank_set[x_parent] > rank_set[y_parent]:
        disjoint_set[x_parent] = y_parent
    else:
        disjoint_set[y_parent] = x_parent
def not_cycle(*item):
    x_parent = get_parent(item[1])
    y_parent = get_parent(item[2])
    if x_parent == y_parent:
        return False;
    make_union(x_parent, y_parent)
    return True

while(edges!=0):
    edge = list(map(int, input().split()))
    heapq.heappush(heap, [edge[2], edge[0], edge[1]])
    edges-=1
cnt = 0
total = 0

while(cnt!=nodes-1):
    item = heapq.heappop(heap)
    if(not_cycle(*item) is True):
        total+= item[0]
        cnt+=1
print(total)

我在python中实现了kruskal算法。我收到RecursionError:比较错误中超出了最大递归深度。 make_union和get_parent是不相交集算法的方法。我在get_parent方法中收到错误。该如何解决?

2 个答案:

答案 0 :(得分:0)

not_cycle中,您是将父母传递给make_union,但是在make_union中,您是在试图重新获得父母。第一次更改后,父母将不再-1,而您将永远递归[1]

[1] 在这种情况下,“永远”是直到堆栈的最大深度。

答案 1 :(得分:0)

 -

   aa,bb=list(map(int,input().split())) 
   c=[] for i in range(bb):
   z=list(map(int,input().split()))
   c.append(z) c.sort(key=lambda x: x[2])    
   a=[]
   b=[] 
   for i in c:
       a.append((i[0]-1,i[1]-1))
       b.append(i[2]) 
   arr=[] 
   size=[] 
   for i in range(len(b)):
       arr.append(i)
       size.append(1)   
   def root(i):
       while arr[i]!=i:
           i=arr[i]
           return i      

  def unions(arr,size,p,q):
       root_a=root(p)
       root_b=root(q)
       if size[root_a]>size[root_b]:
           arr[root_b]=arr[root_a]
           size[root_a]+=size[root_b]
       else:
           arr[root_a]=arr[root_b]
           size[root_b]+=size[root_a]     
  def kruskals(b,a,aa):   
       te=[]
       i=0
       while (len(te))<aa-1:
           (p,q)=a[i]
           if root(p)!=root(q):
                   te.append(b[i])
                   unions(arr,size,p,q)
           i+=1        
       return sum(te)

   print(kruskals(b,a,aa))