http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=28833
题意:就是找起点S到走出n*m格子外的最短时间
开始有一些Fire点,每单位时间会四处延伸
先预处理好每个格子最先着火的时间。
在bfs找最短路的基础上加多一个判断是否着火即可
复杂度(NM)
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <queue> #include <map> #include <set> #include <vector> #include <iostream> using namespace std; const double pi=acos(-1.0); double eps=0.000001; int min(int a,int b) {return a<b?a:b;} int max(int a,int b) {return a>b?a:b;} int r,c; int stx,sty; struct node { int x,y,t; node(){} node(int a,int b,int c){x=a,y=b;t=c;} }; int ok=0; char tm[1005][1005]; int vis[1005][1005]; //着火时间 int dx[]={0,0,1,-1}; int dy[]={1,-1,0,0}; int visited[1005][1005]; //访问过 queue <node> q,que; void fire() { while(!que.empty()) { // printf("%d\n",que.size()); node tt=que.front();que.pop(); int x=tt.x; int y=tt.y; int cur=tt.t; for (int i=0;i<4;i++) { int xx=x+dx[i]; int yy=y+dy[i]; if (!(xx>=1&&xx<=r&&yy>=1&&yy<=c))continue; if (tm[xx][yy]=='#')continue; if (vis[xx][yy]!=-1) continue; vis[xx][yy]=cur+1; que.push(node(xx,yy,cur+1)); } } } int main() { int t;cin>>t; while(t--) { int i,j; ok=0; memset(vis,-1,sizeof vis); memset(visited,0,sizeof visited); cin>>r>>c; for (i=1;i<=r;i++) scanf("%s",tm[i]+1); while(!que.empty()) que.pop(); for (i=1;i<=r;i++) { for (j=1;j<=c;j++) { if (tm[i][j]=='J') {stx=i,sty=j;} if (tm[i][j]=='F') { que.push(node(i,j,0)); vis[i][j]=0; } } } fire(); node st(stx,sty,0); while(!q.empty()) q.pop(); q.push(st); int flag=-1;visited[stx][sty]=1; while(!q.empty()) { node tp=q.front(); q.pop(); for (int i=0;i<4;i++) { int xx=tp.x+dx[i]; int yy=tp.y+dy[i]; if (!(xx>=1&&xx<=r&&yy>=1&&yy<=c)) { flag=tp.t;break; } if (tm[xx][yy]=='#')continue; if (vis[xx][yy]!=-1&&vis[xx][yy]<=tp.t+1)continue; if (visited[xx][yy])continue; q.push(node(xx,yy,tp.t+1)); visited[xx][yy]=1; } if (flag!=-1)break; } if (flag!=-1) printf("%d\n",flag+1); else printf("IMPOSSIBLE\n"); } return 0; }