看了官方题解,整理一下大概的思路
首先是对可以停留的时间进行二分,然后计算mid时间内能否完成逃离
当时为什么没有想到先停留一定的时间再多源Bfs?
因为当时只想着给路径做标记打时间,但是因为要维护的东西太多维护不过来,所以越想越复杂
当时的思路:尝试将火焰蔓延到路径的时间和原本的时间求差,最小值就是可以停留的时间,没有想过预设停留的时间
现在再写一下怎么计算预设时间是否可行
首先在停留的时间中,一直让火焰蔓延,然后再跑多源bfs,如果可以到达终点就可行
注意本题有坑:原本我们在跑多源bfs的时候,如果当前的点刚好背上一次火焰给覆盖了,还是会失败,所以在bfs的时候要判断当前这个点是否还是合法的,如果是终点就自动跳出

class Solution {
public:
    int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
    bool check(int t,vector<vector<int>> grid){
		int m=grid.size(),n=grid[0].size();
		vector<pair<int,int>> f,q;
		//分别代表着火焰和当前路径终点
		for(int i=0;i<m;i++){
			for(int j=0;j<n;j++){
				if(grid[i][j]==1) f.emplace_back(i,j);
			}
		}
		auto fire_spread=[&](){
			vector<pair<int,int>> fn;
			for(auto [u,v]:f){
				for(auto [a,b]:dir){
					int x=u+a,y=v+b;
					if(x>=0&&x<m&&y>=0&&y<n&&grid[x][y]==0){
						grid[x][y]=1;
						fn.emplace_back(x,y);
					}
				}
			}
			f=move(fn);
		};
		while(t--&&f.size()) fire_spread();
		bool vis[m][n];
		memset(vis,0,sizeof vis);
		if(grid[0][0]) return false;
		vis[0][0]=1;
		q.emplace_back(0,0);
		while(q.size()){
			vector<pair<int,int>> fn;
			for(auto [u,v]:q){
                            if(!grid[u][v])//坑点
				for(auto [a,b]:dir){
					int x=u+a,y=v+b;
					if(x>=0&&x<m&&y>=0&&y<n&&grid[x][y]==0&&vis[x][y]==0){
						if(x==m-1&&y==n-1) return true;
						fn.emplace_back(x,y);
						vis[x][y]=1;
					}
				}
			}
			fire_spread();
			q=move(fn);
		}
		return false;
	}
    int maximumMinutes(vector<vector<int>>& grid) {
    	int m=grid.size(),n=grid[0].size();
    	int ans=-1,l=0,r=1e9;
    	while(l<=r){
    		int mid=(l+r)>>1;
    		if(check(mid,grid)){
    			ans=mid;
    			l=mid+1;
    			
    		}
    		else r=mid-1;
    	} 
    	return ans;
    }
};

这好像是一个经典的套路题目,因为第三题写二分调了太久,这场周赛GG