python Dijkstra算法 + 斐波那契堆

def networkDelayTime(self, edges, N, S, D = None):
    # for (d, t) in edges[s], it means that there is a one-way path from s to d with cost t
    # N is the number of all vertexes, S is the source vertex, D if present is the target destination vertex
    
    FAIZ = (1 + math.sqrt(5)) / 2
    nodes = [None] * N
    
    class node(object):
        def __init__(self, i, value):
            self.i = i
            self.val = value
            self.degree = 0
            self.left = self
            self.right = self
            self.parent = None
            self.child = None
            self.marked = False
            nodes[i] = self
    
    def addNode(nd, dbn): #dbn for 'a node in the double-linked list'
        nd.left = dbn.left
        dbn.left.right = nd
        nd.right = dbn
        dbn.left = nd
    
    def heapPush(nd):
        addNode(nd, self.minNode)
    
    def removeNode(nd):
        nd.left.right = nd.right
        nd.right.left = nd.left
    
    def heapPop():
        ret = (self.minNode.i, self.minNode.val)
        mnd = self.minNode
        if mnd.child:
            cur = mnd.child
            while cur:
                child = cur
                cur.parent = None
                removeNode(cur)
                cur = None if cur.right == cur else cur.right
                heapPush(child)
        removeNode(mnd)
        self.minNode = mnd.right
        A = [None] * (int(math.log(self.nodeCount, FAIZ)) + 1)
        while self.minNode:
            x = self.minNode
            removeNode(x)
            self.minNode = None if x.right == x else x.right
            x.left = x.right = x
            d = x.degree
            while A[d]:
                y = A[d]
                if x.val > y.val:
                    x, y = y, x
                removeNode(y)
                if x.child:
                    addNode(y, x.child)
                else:
                    x.child = y
                y.parent = x
                x.degree += 1
                y.marked = False
                A[d] = None
                d += 1
            A[d] = x
        for nd in A:
            if nd:
                if self.minNode:
                    heapPush(nd)
                    if nd.val < self.minNode.val:
                        self.minNode = nd
                else:
                    self.minNode = nd
        self.nodeCount -= 1
        return ret
    
    def cut(child, parent):
        parent.degree -= 1
        parent.child = None if child.right == child else child.right
        child.parent = None
        removeNode(child)
        child.left = child.right = child
        child.marked = False
        heapPush(child)
        
    def cascadingCut(parent):
        pp = parent.parent
        if pp:
            if parent.marked:
                cut(parent, pp)
                cascadingCut(pp)
            else:
                parent.marked = True
        
    def decrease(node, time):
        node.val = time
        parent = node.parent
        if parent and parent.val > node.val:
            cut(node, parent)
            cascadingCut(parent)
        if node.val < self.minNode.val:
            self.minNode = node
        
    dist = [float('inf')] * N
    dist[K] = 0
    prev = [None] * N
    self.minNode = node(K, 0)
    for i in xrange(N):
        if i != K:
            heapPush(node(i, dist[i]))
    self.nodeCount = N
    while self.nodeCount:
        source, time = heapPop()
        if D == source:
            break
        for d, t in edges[source]:
            alt = time + t
            if alt < dist[d]:
                dist[d] = alt
                prev[d] = source
                decrease(nodes[d], alt)

 

你可能感兴趣的:(python Dijkstra算法 + 斐波那契堆)