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

思路:双向广搜,每次从M出发,搜三步,从G出发,搜一步,然后就是判断是否走到对方已经走过的格子,至于魔王的判断,可以用曼哈顿距离。

hdu 3085(双向bfs)_#includehdu 3085(双向bfs)_曼哈顿距离_02
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 #define MAXN 1000
 8 
 9 struct Node{
10     int x,y;
11     Node(){}
12     Node(int xx,int yy):x(xx),y(yy){};
13 }mm,gg,zz[2];
14 
15 bool mark[MAXN][MAXN][2];
16 int n,m,step;
17 char map[MAXN][MAXN];
18 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
19 queue<pair<int,int> >que[2];
20 
21 bool Judge(int x,int y)
22 {
23     if(x>=0&&x<n&&y>=0&&y<m&&map[x][y]!='X'){
24         for(int i=0;i<2;i++){
25             if((abs(x-zz[i].x)+abs(y-zz[i].y))<=2*step)return false;
26         }
27         return true;
28     }
29     return false;
30 }
31 
32 bool bfs(int num)
33 {
34     int size=que[num].size();
35     while(size--){
36         int x=que[num].front().first;
37         int y=que[num].front().second;
38         que[num].pop();
39         if(!Judge(x,y))continue;
40         for(int i=0;i<4;i++){
41             int xx=x+dir[i][0];
42             int yy=y+dir[i][1];
43             if(Judge(xx,yy)){
44                 if(!mark[xx][yy][num]){
45                     if(mark[xx][yy][num^1])return true;
46                     mark[xx][yy][num]=true;
47                     que[num].push(make_pair(xx,yy));
48                 }
49             }
50         }
51     }
52     return false;
53 }
54 
55 
56 int Solve()
57 {
58     memset(mark,false,sizeof(mark));
59     while(!que[0].empty())que[0].pop();
60     while(!que[1].empty())que[1].pop();
61     que[0].push(make_pair(mm.x,mm.y));
62     que[1].push(make_pair(gg.x,gg.y));
63     mark[mm.x][mm.y][0]=mark[gg.x][gg.y][1]=true;
64     step=0;
65     while(!que[0].empty()||!que[1].empty()){
66         step++;
67         if(bfs(0))return step;//mm要搜三步
68         if(bfs(0))return step;
69         if(bfs(0))return step;
70         if(bfs(1))return step;
71     }
72     return -1;
73 }
74 
75 
76 
77 int main()
78 {
79     int _case,index;
80     scanf("%d",&_case);
81     while(_case--){
82         scanf("%d%d",&n,&m);
83         index=0;
84         for(int i=0;i<n;i++){
85             scanf("%s",map[i]);
86             for(int j=0;j<m;j++){
87                 if(map[i][j]=='M')mm=Node(i,j);
88                 else if(map[i][j]=='G')gg=Node(i,j);
89                 else if(map[i][j]=='Z')zz[index++]=Node(i,j);
90             }
91         }
92         printf("%d\n",Solve());
93     }
94     return 0;
95 }
View Code