Codeforces Round #648 (Div. 2) D. Solve The Maze
标签:BFS.
题意:给一个迷宫,‘#’表示墙,‘G’表示好人,’B‘表示坏人,终点在(n,m)。问可否在空地上加上墙,使得所有好人都可以走到终点,所有坏人都无法走到终点。
tips:
A.贪心,考虑在所有坏人周围能加墙的地方加上墙(把坏人围起来)。如果坏人和好人相邻,显然是NO(因为好人所有能去的地方坏人都能去qwq)。
B.如果没有好人,直接输出YES(可以直接把终点堵起来)。【但是注意没有坏人不能直接输出YES,因为好人有可能被墙挡住】。
C.不要对每一个好人跑BFS,这样复杂度太高。因为每个好人如果最后都能到达终点,则从终点开始反向跑BFS,可以经过的好人数目应该就是好人的总数。一次BFS即可。
#include<bits/stdc++.h>
#define m_p make_pair
using namespace std;
int n,m,t,cntgood;
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};
vector<pair<int, int> > bad;
vector<pair<int, int> > :: iterator it;
char mp[55][55];
void init(){
while(!bad.empty()) bad.pop_back();
cntgood = 0;
}
int bfs(){
if(mp[n][m] == '#') return 0;
int cnt = 0;
bool vis[55][55] = {false};
queue<pair<int, int> >q;
q.push(m_p(n, m));
while(!q.empty()){
int xx = q.front().first, yy = q.front().second; q.pop();
if(vis[xx][yy]) continue;
vis[xx][yy] = true;
if(mp[xx][yy] == 'G') cnt++;
for(int k = 0; k < 4; ++k){
int tx = xx + dir[k][0] , ty = yy + dir[k][1];
if(tx < 1 || tx > n || ty < 1 || ty > m || mp[tx][ty] == '#') continue;
q.push(m_p(tx, ty));
}
}
return cnt;
}
void solve(){
init();
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; ++i){
getchar();
for(int j = 1; j <= m; ++j){
scanf("%c",&mp[i][j]);
if(mp[i][j] == 'B') bad.push_back(m_p(i,j));
if(mp[i][j] == 'G') cntgood++;
}
}
if(!cntgood) printf("Yes\n");
else{
for(it = bad.begin(); it != bad.end(); ++it){
int x = it->first, y = it->second;
for(int k = 0; k < 4; ++k){
int tx = x + dir[k][0] , ty = y + dir[k][1];
if(tx < 1 || tx > n || ty < 1 || ty > m) continue;
if(mp[tx][ty] == 'G'){
printf("No\n");
return ;
}else if(mp[tx][ty] == '.') mp[tx][ty] = '#';
}
}
(bfs() == cntgood) ? printf("Yes\n") : printf("No\n");
}
}
int main(){
scanf("%d",&t);
while(t--)
solve();
return 0;
}
/*bool bfs(int x, int y){ //不要这样bfs,对每个人跑bfs太慢
bool vis[55][55] = {false};
queue<pair<int, int> >q;
q.push(m_p(x, y));
while(!q.empty()){
int xx = q.front().first, yy = q.front().second; q.pop();
if(xx == n && yy == m) return true;
if(vis[xx][yy]) continue;
vis[xx][yy] = true;
for(int k = 0; k < 4; ++k){
int tx = xx + dir[k][0] , ty = yy + dir[k][1];
if(tx < 1 || tx > n || ty < 1 || ty > m || mp[tx][ty] == '#') continue;
q.push(m_p(tx, ty));
}
}
return false;
}*/