HDU 3085 Nightmare Ⅱ(双向BFS)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085

 

分别从男生的初始位置,女生的初始位置开始BFS,其中男生BFS每次执行3次,女生BFS每次执行一次。用v1[][]和v2[][]记录每个位置对于男生、女生的可达性。

在每次扩展时,更新新状态与鬼之间的曼哈顿距离,如果小于轮数*2,那么这个新状态时不合法的。

在BFS过程中,如果有一个点(x,y),既能被男生经过,也能被女生经过,则输出当前轮数。

 

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<queue>
 4 #include<cstring>
 5 #include<cmath>
 6 using namespace std;
 7 const int N=805;
 8 int bx,by,gx,gy,px,py,qx,qy,s1,s2;
 9 int T,n,m;
10 char s[N][N];
11 bool v1[N][N],v2[N][N];
12 int dx[4]={0,0,-1,1};
13 int dy[4]={1,-1,0,0};
14 bool check(int x,int y,int k){
15     if(x<1||x>n||y<1||y>m) return 0;
16     if(abs(x-px)+abs(y-py)<=2*k) return 0;
17     if(abs(x-qx)+abs(y-qy)<=2*k) return 0;
18     if(s[x][y]=='X') return 0;
19     return 1;
20 }
21 int BFS(){
22     queue<pair<int,int> > q1,q2;
23     px=0;
24     for(int i=1;i<=n;i++)
25     for(int j=1;j<=m;j++){
26         if(s[i][j]=='M') bx=i,by=j;
27         else if(s[i][j]=='G') gx=i,gy=j;
28         else if(s[i][j]=='Z'){
29             if(!px) px=i,py=j;
30             else qx=i,qy=j;
31         }
32     }
33     int ans=0;
34     memset(v1,0,sizeof(v1));
35     memset(v2,0,sizeof(v2));
36     v1[bx][by]=1; v2[gx][gy]=1;
37     q1.push(make_pair(bx,by));
38     q2.push(make_pair(gx,gy));
39     while(!q1.empty()||!q2.empty()){
40         ans++;
41         for(int tot=1;tot<=3;tot++){
42             s1=q1.size();
43             for(int i=1;i<=s1;i++){
44                 pair<int,int> now=q1.front(); q1.pop();
45                 if(!check(now.first,now.second,ans)) continue;
46                 for(int j=0;j<4;j++){
47                     int nx=now.first+dx[j];
48                     int ny=now.second+dy[j];
49                     if(check(nx,ny,ans)&&!v1[nx][ny]){
50                         v1[nx][ny]=1;
51                         q1.push(make_pair(nx,ny));
52                     }
53                 }
54             }
55         }
56         s2=q2.size();
57         for(int i=1;i<=s2;i++){
58             pair<int,int> now=q2.front(); q2.pop();
59             if(!check(now.first,now.second,ans)) continue;
60             for(int j=0;j<4;j++){
61                 int nx=now.first+dx[j];
62                 int ny=now.second+dy[j];
63                 if(check(nx,ny,ans)&&!v2[nx][ny]){
64                     if(v1[nx][ny]) return ans;
65                     v2[nx][ny]=1;
66                     q2.push(make_pair(nx,ny));
67                 }
68             }
69         }
70     }
71     return -1;
72 }
73 int main(){
74     scanf("%d",&T);
75     while(T--){
76         scanf("%d%d",&n,&m);
77         for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
78         printf("%d\n",BFS());
79     }
80     return 0;
81 }
AC代码

 

posted @ 2020-11-04 21:23  dfydn  阅读(96)  评论(0编辑  收藏  举报