structRegion{// Given m = # of rows and n = # of cols, (x, y) will be hashed as x * n + yunordered_set<int>infected;unordered_set<int>noninfected;// Noninfected neighborsintwallsRequired=0;};classSolution{public:intcontainVirus(vector<vector<int>>&grid){constintm=grid.size();constintn=grid[0].size();intans=0;while(true){vector<Region>regions;vector<vector<bool>>seen(m,vector<bool>(n));for(inti=0;i<m;++i)for(intj=0;j<n;++j)if(grid[i][j]==1&&!seen[i][j]){Regionregion;dfs(grid,i,j,region,seen);// Use DFS to find all regions (1s)if(!region.noninfected.empty())regions.push_back(region);}if(regions.empty())break;// No region causes further infection// Region which infects most neighbors is in the backsort(begin(regions),end(regions),[](constauto&a,constauto&b){returna.noninfected.size()<b.noninfected.size();});// Build walls around the region which infects most neighborsRegionmostInfectedRegion=regions.back();regions.pop_back();ans+=mostInfectedRegion.wallsRequired;for(constintneighbor:mostInfectedRegion.infected){constinti=neighbor/n;constintj=neighbor%n;// The grid is now contained and won't be infected anymoregrid[i][j]=2;}// For remaining regions, expand (infect their neighbors)for(constRegion®ion:regions)for(constintneighbor:region.noninfected){constinti=neighbor/n;constintj=neighbor%n;grid[i][j]=1;}}returnans;}private:voiddfs(constvector<vector<int>>&grid,inti,intj,Region®ion,vector<vector<bool>>&seen){if(i<0||i==grid.size()||j<0||j==grid[0].size())return;if(seen[i][j]||grid[i][j]==2)return;if(grid[i][j]==0){region.noninfected.insert(i*grid[0].size()+j);++region.wallsRequired;return;}// grid[i][j] == 1seen[i][j]=true;region.infected.insert(i*grid[0].size()+j);dfs(grid,i+1,j,region,seen);dfs(grid,i-1,j,region,seen);dfs(grid,i,j+1,region,seen);dfs(grid,i,j-1,region,seen);}};
classRegion{// Given m = # of rows and n = # of cols, (x, y) will be hashed as x * n + ypublicSet<Integer>infected=newHashSet<>();publicSet<Integer>noninfected=newHashSet<>();// Noninfected neighborspublicintwallsRequired=0;};classSolution{publicintcontainVirus(int[][]grid){finalintm=grid.length;finalintn=grid[0].length;intans=0;while(true){List<Region>regions=newArrayList<>();boolean[][]seen=newboolean[m][n];for(inti=0;i<m;++i)for(intj=0;j<n;++j)if(grid[i][j]==1&&!seen[i][j]){Regionregion=newRegion();dfs(grid,i,j,region,seen);// Use DFS to find all regions (1s)if(!region.noninfected.isEmpty())regions.add(region);}if(regions.isEmpty())break;// No region causes further infection// Region which infects most neighbors is in the backCollections.sort(regions,(a,b)->a.noninfected.size()-b.noninfected.size());// Build walls around the region which infects most neighborsRegionmostInfectedRegion=regions.get(regions.size()-1);regions.remove(regions.size()-1);ans+=mostInfectedRegion.wallsRequired;for(finalintneighbor:mostInfectedRegion.infected){finalinti=neighbor/n;finalintj=neighbor%n;// The grid is now contained and won't be infected anymoregrid[i][j]=2;}// For remaining regions, expand (infect their neighbors)for(finalRegionregion:regions)for(finalintneighbor:region.noninfected){finalinti=neighbor/n;finalintj=neighbor%n;grid[i][j]=1;}}returnans;}privatevoiddfs(int[][]grid,inti,intj,Regionregion,boolean[][]seen){if(i<0||i==grid.length||j<0||j==grid[0].length)return;if(seen[i][j]||grid[i][j]==2)return;if(grid[i][j]==0){region.noninfected.add(i*grid[0].length+j);++region.wallsRequired;return;}// grid[i][j] == 1seen[i][j]=true;region.infected.add(i*grid[0].length+j);dfs(grid,i+1,j,region,seen);dfs(grid,i-1,j,region,seen);dfs(grid,i,j+1,region,seen);dfs(grid,i,j-1,region,seen);}}