題意:給1個n*m的網格,上面有的點能走,有的點不能走(墻),然后有的點是火源,火源和人一樣,每次都是上下左右四個方向蔓延,速度一樣是1,火也不可以從墻上跨過去,給你人的起點,終點是只要走到邊界就行,就是走出矩陣,問你最小逃生時間。
思路:需要注意一點是,火源不止一個;首先將所有火結點加入容器(vector),調用bfs時先將火結點加入隊列,其他的和普通bfs就沒什么區別了。
AC代碼如下:
#include<cstdio>#include<queue>#include<cstring>#include<vector>#include<algorithm>using namespace std;const int maxn=1000+10;struct node{ int x,y; int c; //0表示人、1表示火 node(int x=0,int y=0,int c=0):x(x),y(y),c(c){}}nj,nf;int d[maxn][maxn];char g[maxn][maxn];vector<node>vec; //儲存火結點 int R,C;int dir[][2]={{1,0},{-1,0},{0,1},{0,-1}};bool isValid(node &nd){ return nd.x>=0&&nd.x<R && nd.y>=0&&nd.y<C;}void bfs(){ memset(d,0,sizeof(d)); queue<node>q; for(int i=0;i<vec.size();i++){ //先將所有的火結點加入隊列 q.push(vec[i]); d[vec[i].x][vec[i].y]=1; } q.push(nj); //再加入人 d[nj.x][nj.y]=1; while(!q.empty()){ node u=q.front(); q.pop(); if(u.x==0 || u.x==R-1 || u.y==0 || u.y== C-1)//如果到邊界了 if(g[u.x][u.y]=='.' && u.c==0){ PRintf("%d/n",d[u.x][u.y]); return ; } for(int i=0;i<4;i++){ node v=node(u.x+dir[i][0],u.y+dir[i][1],u.c); if(isValid(v) && !d[v.x][v.y] && g[v.x][v.y]=='.' ){ q.push(v); d[v.x][v.y]=d[u.x][u.y]+1; } } } printf("IMPOSSIBLE/n");}int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d%d",&R,&C); getchar(); for(int i=0;i<R;i++){ for(int j=0;j<C;j++){ scanf("%c",&g[i][j]); if(g[i][j]=='J'){nj.x=i;nj.y=j;nj.c=0;} if(g[i][j]=='F'){nf.x=i;nf.y=j;nf.c=1;vec.push_back(nf);} } getchar(); //吃掉換行 } if(nj.x==0 || nj.x==R-1 || nj.y==0 || nj.y==C-1)printf("1/n"); //如果在邊界處 else bfs(); vec.clear(); } return 0;}
新聞熱點
疑難解答