hdu 2612 Find a way(两点bfs)

圣诞节要到了,坤神和瑞瑞这对基佬想一起去召唤师大峡谷开开车。百度地图一下,发现周围的召唤师大峡谷还不少,这对基佬纠结着,该去哪一个。。。坤神:我要去左边的这个(因为离自己比较近 哈哈~)。。瑞瑞:我要去右边的这个(因为离自己比较近 嘿嘿~) ……..这对基佬闹矛盾了,开车有危险了! 为了不让他们去召唤师大峡谷坑人,riot决定让他们去X召唤师大峡谷,保证他俩所走的路程和最短。每走一个点需要花费11分钟,输出他们一共花费多少时间(最短时间噢)

Input

多组测试数据

每组数据,开始一行n,m (2<=n,m<=200)

接下来是个n x m的矩阵

'Y' 表示坤神所在的初始位置

'M' 表示瑞瑞所在的初始位置

'#' 该点禁止通行

'.' 该点可通行

'@' 召唤师大峡谷

Output

每组测试数据,输出坤神和瑞瑞到达同一个召唤师大峡谷所花费的最短时间。

Sample Input

4 4
Y.#@
....
.#..
@..M
4 4
Y.#@
....
.#..
@#.M
5 5
Y..@.
.#...
.#...
@..M.
#...#

Sample Output

66
88
66

Hint

对于第一组样例,坤神和瑞瑞去矩阵(4,1) 这个召唤师大峡谷,耗费的时间为 3 * 11 + 3 * 11 = 66, 去矩阵(1,4)这个召唤师大峡谷,耗费的时间为 5 * 11 + 3 * 11 = 88 。所以,最终答案:66。

其实很简单,,,但我又想多了,,,哎

#include<bits/stdc++.h>
using namespace std;

const int inf = 0x3f3f3f3f;
int n, m, cnt;
char mp[220][220];
bool vis[220][220];//其实没必要标记,a和b已经可以当做标记来用了,此处可删
int a[220][220];//记录Y到各个地方的@的距离
int b[220][220];//记录X到各个地方的@的距离
int d[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};//四个方向

struct node
{
    int x, y, step;
};

void bfs(int x, int y, int l[220][220])
{
    memset(vis, 0, sizeof(vis));
    queue<node> q;
    node a, ne;
    a.x = x; a.y = y; a.step = 0;
    q.push(a);
    vis[x][y] = 1;
    while(!q.empty()){
        a = q.front();
        q.pop();
        if(mp[a.x][a.y] == '@'){
            l[a.x][a.y] = a.step;
            //cout << "l[" <<a.x << "]["<<a.y<<"] = " << l[a.x][a.y] << endl;
        }
        for(int i = 0; i < 4; i++){
            ne.x = a.x + d[i][0];
            ne.y = a.y + d[i][1];
            if(ne.x < 0 || ne.x >= n || ne.y < 0 || ne.y >= m || vis[ne.x][ne.y] == 1 || mp[ne.x][ne.y] == '#')
                continue;
            ne.step = a.step + 1;
            q.push(ne);
            vis[ne.x][ne.y] = 1;
        }
    }
    return;
}

int main()
{
    int i, j, be1, en1, be2, en2, sum;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        sum = inf;
        cnt = 0;
        for(i = 0; i < n; i++)
        {
            scanf("%s", &mp[i]);
            for(j = 0; j < m; j++){
                if(mp[i][j] == 'Y')
                {
                    be1 = i;
                    en1 = j;
                }
                else if(mp[i][j] == 'M')
                {
                    be2 = i;
                    en2 = j;
                }
            }
        }
        //cout << 1 << endl;
        bfs(be1, en1, a);//两次bfs记录他们分别到某个@的距离
       // cout << '1' << endl;
        bfs(be2, en2, b);
        for(i = 0; i < n; i++){
            for(j = 0; j < m; j++){
                if(mp[i][j] == '@' && vis[i][j] == 1){
                    sum = min(sum, a[i][j]+b[i][j]);
                   // cout << "sum = " << sum << endl;
                }
            }
        }
        printf("%d\n", sum*11);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ling_wang/article/details/81543002