HDU 3085 双向bfs 曼哈顿距离 3次bfs

要求:M和G被困在迷宫内,迷宫内有人不可走但是鬼可通过的墙,里面有两个鬼Z,这两个鬼每秒走2步,M每秒走3步,G每秒走1步。M和G若碰到Z则会死掉。问M和G是否能遇见,若能遇见,则最短相遇时间多少。

方法:双向bfs 曼哈顿距离 3次bfs

1.M和G一块走,用双向bfs。双向bfs即2个bfs。

2.M走3步,用3次bfs。注意使用3次bfs时,每次只更新同一步的结点,例如a,b,c是第一次的结点,产生了d,e,f的结点。那么更新时只更新a,b,c,新生成的d,e,f用作下一步更新。因此需要num记录当前的队列大小,只更新num大小的结点。

3.G走1步,用1次bfs。

4.Z走2步,因可以过墙,所以直接用曼哈顿距离即可。

5.曼哈顿距离:d(i,j)=|xi-xj|+|yi-yj|。

#include<iostream>
#include<stdio.h>
#include<queue>
#include<map>
#include<string.h>
#include<math.h>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std ;
int m , n ;
int step ;
int row[4] = {1 , -1 , 0 , 0} ;
int col[4] = {0 , 0 , -1 , 1} ;
char map1[805][805] ;
int vis[2][805][805] ;
int mx , my ;
int gx , gy ;
int zx1 , zy1 ;
int zx2 , zy2 ;
struct node
{
	int x , y ;
} ;
queue <node> q[2] ;
bool bfs(int w)
{
	int i , j ;
	node a , b ;
	int num = q[w].size() ;
	while(num --)
	{
		a = q[w].front() ;
		q[w].pop() ;
		if(abs(zx1 - a.x) + abs(zy1 - a.y) <= 2 * step
		 ||abs(zx2 - a.x) + abs(zy2 - a.y) <= 2 * step)
		   continue ;
		for(i = 0 ; i < 4 ; i ++)
		{
			b.x = a.x + row[i] ;
			b.y = a.y + col[i] ;
			if(b.x < 0 || b.x >= m || b.y < 0 || b.y >= n 
			|| map1[b.x][b.y] == 'X')
			   continue ;
			if(abs(zx1 - b.x) + abs(zy1 - b.y) <= 2 * step
		     ||abs(zx2 - b.x) + abs(zy2 - b.y) <= 2 * step)
		       continue ;
		    if(!vis[w][b.x][b.y])
		    {
		       if(vis[1-w][b.x][b.y])
			   return 1 ;	
		       vis[w][b.x][b.y] = 1 ;
			   q[w].push(b) ;
			   //printf("%d %d %d\n" , w , b.x , b.y) ;	
			}
		}
	}
	return 0 ;
}
void solve()
{
	int i , j ;
	node a , b ;
	zx1 = zy1 = zx2 = zy2 = -1 ;
	for(i = 0 ; i < m ; i ++)
	    for(j = 0 ; j < n ; j ++)
	        if(map1[i][j] == 'M')
	           mx = i , my = j ;
	        else if(map1[i][j] == 'G')
	           gx = i , gy = j ;
	        else if(map1[i][j] == 'Z')
	        {
	        	if(zx1 == -1)
	        	   zx1 = i , zy1 = j ;
	        	else
	        	   zx2 = i , zy2 = j ;
			}
	while(!q[0].empty())
	   q[0].pop() ;
	while(!q[1].empty())
	   q[1].pop() ;
	memset(vis , 0 , sizeof(vis)) ;
	step = 0 ;
	a.x = mx , a.y = my ;
	q[0].push(a) ;
	a.x = gx , a.y = gy ;
	q[1].push(a) ;
	vis[0][mx][my] = 1 ;
	vis[1][gx][gy] = 1 ;
	while(!q[0].empty() || !q[1].empty())
	{
		step ++ ;
 		if(bfs(0))
		{
		   printf("%d\n" , step) ;	
		   return ;
		} 
		if(bfs(0))
		{
		   printf("%d\n" , step) ;	
		   return ;
		} 
		if(bfs(0))
		{
		   printf("%d\n" , step) ;	
		   return ;
		} 
		if(bfs(1))
		{
		   printf("%d\n" , step) ;	
		   return ;
		}
	}
	printf("-1\n") ;
}
int main()
{
	int i , j ;
    int t ;
	scanf("%d" , &t) ;
	while(t--)
	{
	   	scanf("%d%d" , &m , &n) ;
	   	for(i = 0 ; i < m ; i ++)
	   	    scanf("%s" , map1[i]) ;
	   	solve() ;
	}	
} 

猜你喜欢

转载自blog.csdn.net/Irving0323/article/details/86523896