[Python] DFS and simulation. explained
(1) DFS to find all the infected regions\n (2) Pick the region that will infect the largetest number of cells in the next day, and build a wall around it\n (3) 
* (1) DFS to find all the infected regions\n* (2) Pick the region that will infect the largetest number of cells in the next day, and build a wall around it\n* (3) Update the infected regions\nthe cells that are in the wall is updated with "controlled" state (i.e., value 2)\nthe cells that is on the boundary of uncontrolled regions are updated with "infected" state (i.e., value 1)\n* (4) Go back to step (1) until all the regions are controlled or all the cells are infected.\n\n```\nimport heapq\n\nclass Solution:\n    def containVirus(self, isInfected: List[List[int]]) -> int:\n        self.n_row = len(isInfected)\n        self.n_col = len(isInfected[0])\n        self.ifstat = isInfected\n        \n        self.visited = []\n        for _ in range(self.n_row):\n            self.visited.append([False for _ in range(self.n_col)])\n        self.directions = {(0, 1), (1, 0), (0, -1), (-1, 0)}\n        self.infect_region = []\n        self.infect_boundary_wall_cnt = []  # a list of the number of walls required to control a region\n        self.infect_boundary_mheap = [] \n        \n\t\t# step 1: find all the regions that are infected, including the number of walls required to "control" this region\n        visited = copy.deepcopy(self.visited)\n        region_idx = 0\n        for i in range(self.n_row):\n            for j in range(self.n_col):\n                if self.ifstat[i][j] == 1 and (not visited[i][j]):\n                    tr, tb, tbc = list(), set(), [0]\n                    self.dfsFindVirus(i, j, tr, tb, tbc, visited)\n                    self.infect_region.append(tr)\n                    self.infect_boundary_wall_cnt.append(tbc[0])\n                    heapq.heappush(self.infect_boundary_mheap, (-(len(tb)), region_idx, list(tb)))\n                    region_idx += 1\n        \n        # step 2, simulation the progress of virus infection\n        ans = 0\n        while self.infect_boundary_mheap:\n            # pick the region that can infect largest region next day, and build a wall for it\n            _, ridx, _ = heapq.heappop(self.infect_boundary_mheap)\n            for i, j in self.infect_region[ridx]:\n                self.ifstat[i][j] = 2\n            ans += self.infect_boundary_wall_cnt[ridx]\n\t\t\t\n            # update the cells will be infected next day\n            while self.infect_boundary_mheap:\n                _, _, b_list = heapq.heappop(self.infect_boundary_mheap)\n                for i, j in b_list:\n                    self.ifstat[i][j] = 1\n            # check the map and find the new region and boundary\n            visited = copy.deepcopy(self.visited)\n            region_idx = 0\n            t_ir = []\n            t_ibc = []\n            self.infect_boundary_wall_cnt.clear()\n            while self.infect_region:\n                start = self.infect_region.pop()\n                i, j = start[0]\n                if self.ifstat[i][j] == 1 and (not visited[i][j]):\n                    tr, tb, tbc = list(), set(), [0]\n                    self.dfsFindVirus(i, j, tr, tb, tbc, visited)\n                    t_ir.append(tr)\n                    t_ibc.append(tbc[0])\n                    heapq.heappush(self.infect_boundary_mheap, (-(len(tb)), region_idx, list(tb)))\n                    region_idx += 1\n            self.infect_boundary_wall_cnt = t_ibc\n            self.infect_region = t_ir\n        return ans\n        \n        \n    def dfsFindVirus(self, i, j, region, boundary, bcnt, visited):\n        if visited[i][j] or self.ifstat[i][j] == 2:\n            return\n        \n        if self.ifstat[i][j] == 0:\n            # this is a boundary\n            boundary.add((i, j))\n            bcnt[0] += 1\n            return\n        \n        visited[i][j] = True\n        region.append((i, j))\n        \n        for nidx in self.directions:\n            ni = i + nidx[0]\n            nj = j + nidx[1]\n            \n            if ni >= 0 and ni < self.n_row and nj >= 0 and nj < self.n_col and (not visited[ni][nj]):\n                self.dfsFindVirus(ni, nj, region, boundary, bcnt, visited)\n\n        \n```
['Depth-First Search', 'Python3']