HDU 2612 find the way 双向BFS

/*
---------------------------------------------------------
    stratege : BFS,对Y和M的位置,都进行广搜,
               并且Y可以走到M的位置,M可以走
               到Y的位置
    Author :johnsondu
    Time : 2012.2.18 18:25-17:05
    
Problem : 2612 ( Find a way )     Judge Status : Accepted
RunId : 5378860    Language : G++    Author : a312745658
------------------------------------------------------------
*/

#include <iostream>
#include <string.h>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std ;

#define INF 0xfffffff

struct Node
{
    int x, y ;
    int step ;
}cur, next ;

int n, m ;
char map[205][205] ;
bool mark[205][205] ;  //标记是否走过
int num1[205][205] ;   //标记Y走到@的所用时间
int num2[205][205] ;   //标记M走到@的所用时间,均初始化为0

bool flag ;
int Ysx, Ysy, Msx, Msy ; //y和m的起始位置
int dir[4][2] = {1, 0, 0, -1, -1, 0, 0, 1} ; //右下左上


void init ()                    // 输入
{
    int i, j ;
    for (i = 0; i < n; i ++)
        for (j = 0; j < m; j ++)
        {
            cin >> map[i][j] ;
            if (map[i][j] == 'Y')
                Ysx = i, Ysy = j ;

            if (map[i][j] == 'M')
                Msx = i, Msy = j ;
            num1[i][j] = 0 ;  //初始化所用时间为0
            num2[i][j] = 0 ;
        }
    flag = false ;
}

int max (int a, int b)
{
    return a > b ? a : b ;
}

int min (int a, int b)
{
    return a > b ? b : a ;
}

bool Check (int a, int b)
{
    if (a >= 0 && b >= 0 && a < n && b < m && map[a][b] != '#')  //未越界,不是障碍,没走过
        return true ;

    return false ;
}

void BFS1 ()
{
    int i, j, k ;

    cur.x = Ysx ;
    cur.y = Ysy ;
    cur.step = 0 ;
    queue <Node> Q ;
    Q.push (cur) ;                  //入队
    mark[cur.x][cur.y] = true ;     //标记

    while (! Q.empty())
    {
        cur = Q.front () ;
        Q.pop () ;
        if (map[cur.x][cur.y] == '@') //时间赋值给当前时间,注意num1初始化为0,max函数
        {
            num1[cur.x][cur.y] = max(num1[cur.x][cur.y], cur.step) ;
        }

        for (i = 0; i < 4; i ++)
        {
            next.x = cur.x + dir[i][0] ;
            next.y = cur.y + dir[i][1] ;
            next.step = cur.step + 11 ;

            if (Check(next.x, next.y) && !mark[next.x][next.y])  //未越界,不是障碍,没走过,则可走。
            {
                mark[next.x][next.y] = true ; //标记
                Q.push (next) ;
            }
        }
    }
}

void BFS2 ()
{
    int i, j, k ;

    cur.x = Msx ;
    cur.y = Msy ;
    cur.step = 0 ;
    queue <Node> Q ;
    Q.push (cur) ;
    mark[cur.x][cur.y] = true ;

    while (! Q.empty())
    {
        cur = Q.front () ;
        Q.pop () ;
        if (map[cur.x][cur.y] == '@')
        {
            num2[cur.x][cur.y] = max(num2[cur.x][cur.y], cur.step) ;
        }

        for (i = 0; i < 4; i ++)
        {
            next.x = cur.x + dir[i][0] ;
            next.y = cur.y + dir[i][1] ;
            next.step = cur.step + 11 ;

            if (Check(next.x, next.y) && !mark[next.x][next.y])
            {
                mark[next.x][next.y] = true ;
                Q.push (next) ;
            }
        }
    }
}

int main()
{
    int i, j ;
    while (cin >> n >> m)
    {
        init () ;
        memset (mark, false, sizeof(mark)) ; // 每次走过,要单独重新清除标记。
        BFS1 () ;

        memset (mark, false, sizeof(mark)) ;
        BFS2 () ;

        int ans = INF ;
        for (i = 0; i < n; i ++)
            for (j = 0; j < m; j ++)
            {
                if (num1[i][j] && num2[i][j])       //开始初始化为0,若能走到@,则此时时间一定大于0
                    ans = min (num1[i][j] + num2[i][j], ans) ; //选取所有符合情况的最少的时间
            }

        cout << ans << endl ;
    }
    return 0 ;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值