hdu 3085(双向bfs)

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

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

 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

 

你可能感兴趣的:(HDU)