my python solution, inspired by A* algorithm
The expected min distance between p1 and p2 is d = abs(p1[0] - p2[0]) + abs(p1[1] - p2[1]). \nFrom p1 (or the following positions), we may have two choices, mov
The expected min distance between p1 and p2 is d = abs(p1[0] - p2[0]) + abs(p1[1] - p2[1]). \nFrom p1 (or the following positions), we may have two choices, move a step towards p2 or a step far away from p2 (if we do this, the min distance we can expect is d + 2, so we needn't think about them until all the expected min distance way are blocked). \nAnd I use stack to find the possible way greedily. \nHere is my code:\n```\nclass Solution(object):\n    def cutOffTree(self, forest):\n        """\n        :type forest: List[List[int]]\n        :rtype: int\n        """\n        nrow, ncol = len(forest), len(forest[0])\n        forest.append([0] * ncol)\n        for row in forest:\n            row.append(0)\n\n        trees = {(i, j) for i in range(nrow) for j in range(ncol)\n                 if forest[i][j] > 1}\n\n        canReach = {(0, 0)}\n        stack = [(0, 0)]\n        while stack:\n            i, j = stack.pop()\n            for i2, j2 in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)):\n                if forest[i2][j2] != 0 and (i2, j2) not in canReach:\n                    canReach.add((i2, j2))\n                    stack.append((i2, j2))\n\n        if trees.difference(canReach):\n            return -1\n\n        def get_sp(p1, p2):\n            theMin = abs(p1[0] - p2[0]) + abs(p1[1] - p2[1])\n            stack1, stack2 = [p1], []\n            used, visited = {p1}, {p1}\n\n            while 1:\n                if not stack1:\n                    stack1, stack2 = stack2, stack1\n                    used.update(stack1)\n                    theMin += 2\n\n                p = stack1.pop()\n                if p == p2:\n                    break\n\n                i, j = p\n                add1, add2 = [], []\n\n                if i == p2[0]:\n                    add2.append((i - 1, j))\n                    add2.append((i + 1, j))\n                elif i < p2[0]:\n                    add2.append((i - 1, j))\n                    add1.append((i + 1, j))\n                else:\n                    add1.append((i - 1, j))\n                    add2.append((i + 1, j))\n\n                if j == p2[1]:\n                    add2.append((i, j - 1))\n                    add2.append((i, j + 1))\n                elif j < p2[1]:\n                    add2.append((i, j - 1))\n                    add1.append((i, j + 1))\n                else:\n                    add1.append((i, j - 1))\n                    add2.append((i, j + 1))\n\n                for v in add1:\n                    if forest[v[0]][v[1]] != 0 and v not in used:\n                        visited.add(v)\n                        used.add(v)\n                        stack1.append(v)\n                for v in add2:\n                    if forest[v[0]][v[1]] != 0 and v not in visited:\n                        visited.add(v)\n                        stack2.append(v)\n\n            return theMin\n\n        seq = sorted(trees, key=lambda x: forest[x[0]][x[1]])\n        if seq[0] != (0, 0):\n            seq.insert(0, (0, 0))\n        return sum(get_sp(seq[i], seq[i + 1]) for i in range(len(seq) - 1))\n```
[]