Safe Path(bfs+一维数组存图)

题目链接:http://codeforces.com/gym/101755/problem/H

题目分析:先bfs一遍怪兽可以到达的点,再bfs人可以走的地方看可不可以到达终点;

     很显然读到  2<=n*m<=200000 时,就不可以用二维数组存图了,不过据说因为数据比较水,可以用vector存图;

vector存图AC代码:

  1 /* */
  2 # include <iostream>
  3 # include <stdio.h>
  4 # include <string.h>
  5 # include <string>
  6 # include <cmath>
  7 # include <climits>
  8 # include <cctype>
  9 # include <ctime>
 10 # include <algorithm>
 11 # include <functional>
 12 # include <bitset>
 13 # include <set>
 14 # include <map>
 15 # include <deque>
 16 # include <queue>
 17 # include <stack>
 18 # include <vector>
 19 using namespace std;
 20 
 21 const int maxn=2e5+7;
 22 vector<char>mp[maxn];
 23 vector<int>dis[maxn];
 24 vector<int>vis[maxn];
 25 int n, m;
 26 
 27 struct node
 28 {
 29     int x, y;
 30     int step;
 31 }cur, after;
 32 
 33 int dir[4][2]={{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
 34 int sx, sy, fx, fy;
 35 
 36 int check(int x, int y)
 37 {
 38     if( x>=0 && x<n && y>=0 && y<m )
 39         return 1;
 40     return 0;
 41 }
 42 
 43 void bfs1(int d)
 44 {
 45     queue<node>q;
 46     int i, j;
 47     for( i=0; i<n; i++ )
 48     {
 49         for( j=0; j<m; j++ )
 50         {
 51             if( mp[i][j]=='M' )
 52             {
 53                 cur.x = i;
 54                 cur.y = j;
 55                 cur.step = 0;
 56                 q.push(cur);
 57                 dis[i][j] = 1;
 58             }
 59         }
 60     }
 61 
 62     while( !q.empty() )
 63     {
 64         cur = q.front();
 65         q.pop();
 66         for(int i=0; i<4; i++ )
 67         {
 68             after.x = cur.x+dir[i][0];
 69             after.y = cur.y+dir[i][1];
 70             after.step = cur.step + 1;
 71 
 72             if( check(after.x, after.y) )
 73             {
 74                 if( !dis[after.x][after.y] && after.step<=d )
 75                 {
 76                     dis[after.x][after.y] = 1;
 77                     q.push(after);
 78                 }
 79             }
 80         }
 81     }
 82 }
 83 
 84 void bfs2(int x, int y)
 85 {
 86     cur.x = x;
 87     cur.y = y;
 88     cur.step = 0;
 89     queue<node>q;
 90     q.push(cur);
 91     vis[x][y] = 1;
 92     if( dis[x][y] )
 93     {
 94         printf("-1\n");
 95         return ;
 96     }
 97     while( !q.empty() )
 98     {
 99         cur = q.front();
100         q.pop();
101         if( mp[cur.x][cur.y]=='F' )
102         {
103             printf("%d\n", cur.step);
104             return ;
105         }
106         for(int i=0; i<4; i++ )
107         {
108             after.x = cur.x + dir[i][0];
109             after.y = cur.y + dir[i][1];
110             after.step = cur.step + 1;
111             if( check(after.x, after.y) )
112             {
113                 if( !dis[after.x][after.y] && !vis[after.x][after.y])
114                 {
115                     vis[after.x][after.y] = 1;
116                     q.push(after);
117                 }
118             }
119         }
120     }
121     printf("-1\n");
122     return ;
123 }
124 int main()
125 {
126     int d, i, j;
127     cin>>n>>m>>d;
128     char s;
129 
130     for(i=0; i<n; i++)
131     {
132         mp[i].clear();
133         vis[i].clear();
134         dis[i].clear();
135     }
136 
137     for(i=0; i<n; i++ )
138     {
139         for(j=0; j<m; j++ )
140         {
141             cin>>s;
142             mp[i].push_back(s);
143             dis[i].push_back(0);
144             vis[i].push_back(0);
145         }
146     }
147     bfs1(d);
148 
149     for(i=0; i<n; i++ )
150     {
151         for( j=0; j<m; j++ )
152         {
153             if( mp[i][j]=='F' )
154             {
155                 fx = i;
156                 fy = j;
157             }
158             if( mp[i][j]=='S' )
159             {
160                 sx = i;
161                 sy = j;
162             }
163         }
164     }
165 
166     if( dis[fx][fy] )
167     {
168         printf("-1\n");
169     }
170     else
171     {
172         bfs2(sx, sy);
173     }
174     return 0;
175 }
View Code

 

这道题也让我知道了可以用一位数组存图:

详细的见代码注释:

AC代码:

  1 /* */
  2 # include <iostream>
  3 # include <stdio.h>
  4 # include <string.h>
  5 # include <algorithm>
  6 # include <cctype>
  7 # include <ctime>
  8 # include <functional>
  9 # include <cmath>
 10 # include <bitset>
 11 # include <deque>
 12 # include <queue>
 13 # include <stack>
 14 # include <vector>
 15 # include <set>
 16 # include <map>
 17 # include <climits>
 18 using namespace std;
 19 
 20 typedef long long LL;
 21 const int maxn=1e6+100;
 22 int n, m, t;
 23 int a[maxn], d;
 24 char str[maxn];
 25 bool vis[maxn];///标记是否已经访问过
 26 int dis[maxn];///记录步数
 27 int dd[maxn];///dd[]为0,说明怪兽到不了,dd不为0说明怪兽可以到此处
 28 int cnt, fx, fy, sx, sy;
 29 int dir[4][2]={{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
 30 struct node
 31 {
 32     int x;
 33     int y;
 34 }g[maxn], cur, after;
 35 
 36 bool check(int a, int b)
 37 {
 38     if( a>=1 && b>=1 && a<=n && b<=m && !dd[a*m+b] )
 39         return true;
 40     return false;
 41 }
 42 
 43 void bfs()
 44 {
 45     queue<node>q;
 46     cur.x = sx;
 47     cur.y = sy;
 48     vis[cur.x*m+cur.y] = 1;
 49     q.push(cur);
 50 
 51     while( !q.empty())
 52     {
 53         cur = q.front();
 54         q.pop();
 55         for(int i=0; i<4; i++ )
 56         {
 57             int xx = cur.x + dir[i][0];
 58             int yy = cur.y + dir[i][1];
 59 
 60             if( check(xx, yy) && !vis[xx*m+yy])
 61             {
 62                 dis[xx*m+yy] = dis[cur.x*m+cur.y]+1;
 63                 vis[xx*m+yy] = 1;
 64                 after.x = xx;
 65                 after.y = yy;
 66                 q.push(after);
 67             }
 68         }
 69     }
 70     return ;
 71 }
 72 
 73 void bfss()///广搜怪兽可以到达的地方
 74 {
 75     queue<node>q;
 76     for(int i=0; i<cnt; i++ )
 77         q.push(g[i]);
 78 
 79     while( !q.empty() )
 80     {
 81         cur=q.front();
 82         q.pop();
 83 
 84         if( dd[cur.x*m+cur.y]==0 )
 85             continue;
 86 
 87         for(int i=0; i<4; i++ )
 88         {
 89             int xx = cur.x + dir[i][0];
 90             int yy = cur.y + dir[i][1];
 91             if( check(xx, yy) )
 92             {
 93                 after.x = xx;
 94                 after.y = yy;
 95                 dd[xx*m+yy] = dd[cur.x*m+cur.y]-1;
 96                 q.push(after);
 97             }
 98         }
 99     }
100     return ;
101 }
102 
103 int main()
104 {
105     while( ~ scanf("%d %d %d", &n, &m, &d) )
106     {
107         getchar();
108         for(int i=1; i<=n; i++ )
109             scanf("%s", &str[i*m+1]);///一维数组存图
110 
111         memset(vis, false, sizeof(vis));
112         memset(dd, 0, sizeof(dd));
113         memset(dis, 0, sizeof(dis));
114 
115         for(int i=1; i<=n; i++ )
116         {
117             for(int j=1; j<=m; j++ )
118             {
119                 if( str[i*m+j]=='S' )
120                 {
121                     sx = i;
122                     sy = j;
123                 }
124 
125                 else if( str[i*m+j]=='F' )
126                 {
127                     fx = i;
128                     fy = j;
129                 }
130 
131                 else if( str[i*m+j]=='M' )
132                 {
133                     dd[i*m+j] = d+1;
134                     cur.x = i;
135                     cur.y = j;
136                     g[cnt++] = cur;
137                 }
138             }
139         }
140 
141         bfss();
142         if( dd[sx*m+sy] || dd[fx*m+fy] )
143         {
144             printf("-1\n");
145         }
146         else
147         {
148             bfs();
149             if( !vis[fx*m+fy] )
150                 printf("-1\n");
151             else
152                 printf("%d\n", dis[fx*m+fy]);
153         }
154     }
155     return 0;
156 }
View Code

 

posted @ 2019-08-09 14:53  swsyya  阅读(339)  评论(0编辑  收藏  举报

回到顶部