fzu 2150 双起点bfs

题意:

n*m的方格,每个方格是草或空地。(x,y)有草且在t时刻着火,那么(x+1, y), (x-1, y), (x, y+1), (x, y-1)中有草的方格在t+1时刻会着火。找两个有草的方格在0时刻放火,这两个方格能重合。问是否能将所有的草点燃,若可以,输出最短时间,若不可以,输出-1。

1 <= n <=10, 1 <= m <=10。

题解:

1.双起点bfs

2.注意两个起点可以重合

//#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std ; 
#define N 15
#define inf 0x3f3f3f3f
using namespace std ;
int n , m ;
int num ;
int step[N][N] ;
char map1[N][N] ;
int id[N][N] ;
int row[4] = {-1 , 1 , 0 , 0} ;
int col[4] = {0 , 0 , -1 , 1} ;
struct node
{
	int x , y ;
} ;
int bfs(int x , int y , int xx , int yy)
{
	int i , j ;
    int ans = 0 ;
    node a , b ;
    memset(step , inf , sizeof(step)) ;
	queue <node> q ;
	a.x = x ;
	a.y = y ;
	b.x = xx ;
	b.y = yy ;
	step[a.x][a.y] = 0 ;
	step[b.x][b.y] = 0 ;
	q.push(a) ;
	q.push(b) ;
	while(!q.empty())
	{
		a = q.front() ;
		q.pop() ;
		for(i = 0 ; i < 4 ; i ++)
		{
			b.x = a.x + row[i] ;
			b.y = a.y + col[i] ;
			if(b.x < 0 || b.x >= n || b.y < 0 || b.y >= m)
			   continue ;
			if(map1[b.x][b.y] == '.' || step[b.x][b.y] != inf)
			   continue ;
			step[b.x][b.y] = step[a.x][a.y] + 1 ;
			ans = max(ans , step[b.x][b.y]) ;
			q.push(b) ;
 		}
	}
	return ans ;
}
int judge()
{
	int i , j ;
	int ans = 0 ;
	for(i = 0 ; i < n ; i ++)
       for(j = 0 ; j < m ; j ++)
         if(map1[i][j] == '#')
           ans = max(ans , step[i][j]) ;
    return ans ;
}
int main()
{
	int i , j , k , p , q ;
	int ans ;
    int t ;
    scanf("%d" , &t) ;
    for(k = 1 ; k <= t ; k ++)
    {
    	scanf("%d%d" , &n , &m) ;
    	for(i = 0 ; i < n ; i ++)
    	   scanf("%s" , map1[i]) ;
    	ans = inf ;
    	for(i = 0 ; i < n ; i ++)
    	   for(j = 0 ; j < m ; j ++)
    	      for(p = 0 ; p < n ; p ++)
    	         for(q = 0 ; q < m ; q ++)
    	           if(map1[i][j] == '#' && map1[p][q] == '#')
    	           {
    	           	  bfs(i , j , p , q) ;
    	           	  ans = min(ans , judge()) ;
	 			   }
	    if(ans == inf)
	       ans = -1 ;
	    printf("Case %d: %d\n" , k , ans) ;
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值