Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import copy
- class InvalidHeapSize(Exception):
- def __init__(self):
- pass
- def __repr__(self):
- return 'Tried to create heap non-positive size'
- class InvalidHeapPosition(Exception):
- def __init__(self, pos, size):
- self.pos, self.size = pos, size
- def __repr__(self):
- return f'Invalid position ({self.pos}), position must be in [0; {self.size})'
- class EmptyHeapException(Exception):
- def __init__(self):
- pass
- def __repr__(self):
- return 'You can not use remove_top, heap size is 0'
- class Heap:
- __inf__ = 10**18+1
- def __init__(self, initial_length: int):
- if initial_length <= 0:
- raise InvalidHeapSize
- self.initial_length = initial_length
- self.size = 1
- while self.size < initial_length:
- self.size *= 2
- self.shift = self.size-1
- self.data_size = self.size
- self.size = 2*self.size-1
- self.items = [[self.__inf__, None] for i in range(self.size)]
- @staticmethod
- def parent(pos):
- return (pos-1)//2
- @staticmethod
- def left_child(pos):
- return pos*2+1
- @staticmethod
- def right_child(pos):
- return pos*2+2
- def set(self, position: int, value: int):
- if position < 0 or position > self.initial_length:
- raise InvalidHeapPosition(position, self.initial_length)
- self.items[self.shift+position] = [value, position]
- self.go_top(self.shift+position)
- def go_top(self, position):
- while position > 0:
- parent = self.parent(position)
- if self.items[position][0] < self.items[parent][0]:
- self.items[parent] = copy.copy(self.items[position])
- position = parent
- else:
- break
- def update_from_bottom(self, position):
- while position > 0:
- position = self.parent(position)
- left, right = self.left_child(position), self.right_child(position)
- smaller = left if self.items[left][0] < self.items[right][0] else right
- self.items[position] = copy.copy(self.items[smaller])
- def remove_top(self):
- if self.items[0][1] is None:
- raise EmptyHeapException
- position = self.items[0][1]
- self.items[self.shift+position] = [self.__inf__, None]
- self.update_from_bottom(self.shift+position)
- def get(self):
- return self.items[0][1]
- def __repr__(self):
- return 'Heap:\n'+'\n'.join(f'{key}: {value}' for key, value in self.items)
- def main():
- n, start, finish = list(map(int, input().split()))
- start -= 1
- finish -= 1
- edges = [[] for i in range(n)]
- for i in range(n):
- data = list(map(int, input().split()))
- for index, edge in zip(range(n), data):
- if edge > 0:
- edges[i].append((index, edge))
- heap = Heap(n)
- w = [10**18]*n
- w[start] = 0
- for i in range(n):
- heap.set(i, 10**18)
- heap.set(start, 0)
- for k in range(n):
- ver = heap.get()
- for index, edge in edges[ver]:
- if w[index] > w[ver]+edge:
- w[index] = w[ver]+edge
- heap.set(index, w[ver]+edge)
- heap.remove_top()
- if w[finish] >= 10**18:
- print(-1)
- else:
- print(w[finish])
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement