UVA 11624 Fire!BFS 图论

题目大意:有火,火会扩散,找出逃出迷宫的最短路
两次Bfs,一次标记火的扩散,一次标记人的;
人不会被火烧的判定条件是其步数小于火的步数。

最后在迷宫的四条边界上找最小的ans

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int INF=1000000000+10;
const int maxn=1000+10;
int R,C,ans;
char maze[maxn][maxn];
int xx[4]={0,0,1,-1};
int yy[4]={1,-1,0,0};
int vis[maxn][maxn][2],d[maxn][maxn][2];

struct Node{
	int x,y;
	Node(int x,int y):x(x),y(y){}
};
queue<Node>Q;
bool check(int r,int c,int kind){
	if(r<0||r>=R ||c<0||c>=C)return false;
	if(vis[r][c][kind]==1)return false;
	return true;
}

void bfs(int kind){
	while(!Q.empty()){
		Node now=Q.front();Q.pop();
		int r=now.x,c=now.y;
		for(int i=0;i<4;i++){
			int rr=r+xx[i],cc=c+yy[i];
			if(!check(rr,cc,kind))continue;
			vis[rr][cc][kind]=1;
			d[rr][cc][kind]=d[r][c][kind]+1;
			Q.push(Node(rr,cc));
		}
	}
}
void find(int r,int c){
	if(!vis[r][c][0])return;
	if(!vis[r][c][1] || d[r][c][0]<d[r][c][1])ans=min(ans,d[r][c][0]+1);
}
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		memset(vis,0,sizeof(vis));
		memset(d,0,sizeof(d));
		vector<Node>fire;
		scanf("%d%d",&R,&C);
		for(int i=0;i<R;i++){
			scanf("%s",maze[i]);
			for(int j=0;j<C;j++){
				if(maze[i][j]=='#'){vis[i][j][0]=vis[i][j][1]=1;}
				else if(maze[i][j]=='J')Q.push(Node(i,j));
				else if(maze[i][j]=='F')fire.push_back(Node(i,j));
			}
		}
        
		Node node=Q.front();
		vis[node.x][node.y][0]=1;
		bfs(0);
        
		for(int i=0;i<fire.size();i++){
		    vis[fire[i].x][fire[i].y][1] = 1;
			Q.push(fire[i])	;
		}
		bfs(1);
		ans=INF;
        
		for(int i=0;i<R;i++){find(i,0);find(i,C-1);}
		for(int i=0;i<C;i++){find(0,i);find(R-1,i);}
		if(ans==INF)printf("IMPOSSIBLE\n");
		else printf("%d\n",ans);
		
		
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/love_phoebe/article/details/80341124