1. 程式人生 > 實用技巧 >HDU 3085 Nightmare Ⅱ(雙向BFS)

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程式碼