[Python3] min heap + BFS
\n# Min Heap + BFS\nclass Solution:\n    def cutOffTree(self, forest: List[List[int]]) -> int:\n        # 1. use min heap to sort the tree by height\n        he
```\n# Min Heap + BFS\nclass Solution:\n    def cutOffTree(self, forest: List[List[int]]) -> int:\n        # 1. use min heap to sort the tree by height\n        heap = []\n        for r in range(len(forest)):\n            for c in range(len(forest[0])):\n                if forest[r][c] > 1:\n                    heapq.heappush(heap, (forest[r][c], r, c))\n\n        totalSteps, currR, currC = 0, 0, 0\n        while heap:\n            height, r, c = heapq.heappop(heap)\n            steps = self.bfsGetMinSteps(forest, currR, currC, r, c)\n            if steps == -1:\n                return -1\n            currR, currC = r, c\n            totalSteps += steps    \n        return totalSteps\n    \n    # 2. use BFS get min distance for tree to tree\n    def bfsGetMinSteps(self, forest, currR, currC, targetR, targetC):\n        directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]\n        m, n = len(forest), len(forest[0])\n        q  = collections.deque([(currR, currC)])\n        visited = set([(currR, currC)])\n        steps = 0\n        \n        while q:\n            sameLevelCounts = len(q)\n            for _ in range(sameLevelCounts):\n                r, c = q.popleft()\n                if r == targetR and c == targetC:\n                    return steps\n                for dr, dc in directions:\n                    nextR, nextC = r + dr, c + dc\n                    if 0 <= nextR < m and 0 <= nextC < n and (nextR, nextC) not in visited and forest[nextR][nextC] != 0:\n                        visited.add((nextR, nextC))\n                        q.append((nextR, nextC))\n            steps += 1\n        return -1\n```
['Breadth-First Search', 'Heap (Priority Queue)', 'Python']