Fire! UVA - 11624(bfs(多个起点))

题目链接:https://cn.vjudge.net/problem/UVA-11624

一开始以为只有一个F,WA的不知所措,看了评论说有多个F

思路:将所有F入队列,进行广搜,得到F到每个‘.’的最短时间。再将人J进行广搜,得到J到每个'.'的最时间。判断人到边缘上的'.'需要的时间是否小于F到该点的时间,然后找出最短时间。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <stack>
  6 #include <algorithm>
  7 #include <cmath>
  8 #include <map>
  9 #define mem(a,b) memset(a,b,sizeof(a));
 10 using namespace std;
 11 #define INF 0x3f3f3f3f
 12 typedef long long ll;
 13 int dir[4][2] = {0,1,0,-1,1,0,-1,0};
 14 const int maxn = 5000005;
 15 int r,c,vis1[1005][1005],vis2[1005][1005];
 16 ll sum1[1005][1005],sum2[1005][1005];
 17 string s[1005];
 18 struct NNode{
 19     int x,y;
 20     NNode(int x1,int y1):x(x1),y(y1){};
 21 };
 22 queue<NNode>Q;
 23 struct Node{
 24     ll x,y,num;
 25     Node(int x1,int y1,int n1):x(x1),y(y1),num(n1){};
 26 };
 27 void bfs1() {
 28     queue<Node>q;
 29     while(!Q.empty()){
 30     NNode T = Q.front();
 31     Q.pop();
 32     vis1[T.x][T.y] = 1;
 33     q.push(Node(T.x,T.y,0));
 34     }
 35 
 36     while(!q.empty()) {
 37         Node temp = q.front();
 38         q.pop();
 39         for(int i = 0; i < 4; i++) {
 40             int fx = temp.x + dir[i][0],fy = temp.y + dir[i][1];
 41             if(!vis1[fx][fy] && s[fx][fy] != '#' && fx >=0 && fx < r && fy >=0 && fy < c)
 42             {
 43                 vis1[fx][fy] = 1;
 44                 sum1[fx][fy] = temp.num+1;
 45                 q.push(Node(fx,fy,temp.num+1));
 46             }
 47         }
 48     }
 49 }
 50 void bfs2(int x1,int y1) {
 51     queue<Node>q;
 52     q.push(Node(x1,y1,0));
 53     sum2[x1][y1] = 0;
 54     while(!q.empty()) {
 55         Node temp = q.front();
 56         q.pop();
 57         for(int i = 0; i < 4; i++) {
 58             int fx = temp.x + dir[i][0],fy = temp.y + dir[i][1];
 59             if(!vis2[fx][fy] && s[fx][fy] == '.' && fx >=0 && fx < r && fy >=0 && fy < c)
 60             {
 61                 vis2[fx][fy] = 1;
 62                 sum2[fx][fy] = temp.num+1;
 63                 q.push(Node(fx,fy,temp.num+1));
 64             }
 65         }
 66     }
 67 }
 68 int main()
 69 {
 70     int t;
 71     cin >> t;
 72     while(t--) {
 73         mem(sum1,INF);
 74         mem(sum2,INF);
 75         mem(vis1,0);
 76         mem(vis2,0);
 77         cin >> r >> c;
 78         for(int i = 0; i < r; i++) {
 79             cin >> s[i];
 80         }
 81         for(int i = 0; i < r; i++) {
 82             for(int j = 0; j < c; j++) {
 83                 if(s[i][j] == 'J') {
 84                     vis2[i][j] = 1;
 85                     bfs2(i,j);//搜索人到每个'.'的时间
 86                 }
 87                 else if(s[i][j] == 'F') {
 88                     Q.push(NNode(i,j));//将所有F入队列
 89                 }
 90             }
 91         }
 92         bfs1();//搜索F到每个'.'的最短时间
 93         ll ans = INF;
 94         for(int i = 0;i < r;i ++) {//判断边缘第一列和最后一列的点
 95                 if((s[i][0] == '.'||s[i][0] == 'J') && vis2[i][0] && sum2[i][0] < sum1[i][0])
 96                    ans = min(ans,sum2[i][0]);
 97                 if((s[i][c-1] == '.'||s[i][c-1] == 'J') && vis2[i][c-1] && sum2[i][c-1] < sum1[i][c-1])
 98                    ans = min(ans,sum2[i][c-1]);
 99         }
100         for(int i = 0;i < c;i ++) {//判断边缘第一行和最后一行的点
101                 if((s[0][i] == '.'||s[0][i] == 'J') && vis2[0][i] && sum2[0][i] < sum1[0][i])
102                    ans = min(ans,sum2[0][i]);
103                 if((s[r-1][i] == '.'||s[r-1][i] == 'J') && vis2[r-1][i] && sum2[r-1][i] < sum1[r-1][i])
104                    ans = min(ans,sum2[r-1][i]);
105         }
106         if(ans == INF)
107         cout << "IMPOSSIBLE" << endl;
108         else
109             cout << ans+1 << endl;//答案最后要加一因为还要从边缘上的点出去
110     }
111     return 0;
112 }

 

posted on 2019-08-19 13:56  一只小毛球  阅读(400)  评论(0编辑  收藏  举报

导航