HDU 2612 Find a way (BFS)


**链接 : ** Here!

**思路 : ** 两遍BFS, 第一次是从 'Y' 搜索, 搜到 '@' 就将其累加到一个数组中, 这里采用将二维坐标点映射成一维的点, 第二次从 'M' 搜索, 搜到 '@' 就将其累加到一个数组中, 最后扫描一遍地图, 将 $ans$ 更新为字符为 '@' 的累加值最小值. 最后答案就是 $ans * 11$


/*************************************************************************
	> File Name: 2612-Find-a-way.cpp
	> Author: 
	> Mail: 
	> Created Time: 2017年11月29日 星期三 20时02分14秒
 ************************************************************************/

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

#define MAX_N 300
const int INF = 0x3f3f3f;
int n, m;
int cnt[MAX_N * MAX_N] = {0}; // 相当于是个hash表, 将所有二维点映射进去
int vis[MAX_N][MAX_N];
int dx[4] = {0, 0, -1, 1};
int dy[4] = {-1, 1, 0, 0};
char G[MAX_N][MAX_N];
struct Point {
    Point () {}
    Point (int x, int y, int step) : x(x), y(y), step(step) {}
    int x, y, step;
};

bool check(Point pt) {
    return !(pt.x < 0 || pt.x >= n || pt.y < 0 || pt.y >= m || vis[pt.x][pt.y] || (G[pt.x][pt.y] == '#'));
}
void solve(Point st) {
    queue<Point> que;
    que.push(st);
    vis[st.x][st.y] = 1;
    while(!que.empty()) {
        Point now = que.front();
        que.pop();
        for (int i = 0 ; i < 4 ; ++i) {
            Point temp(now.x + dx[i], now.y + dy[i], now.step + 1);
            if (!check(temp)) continue;
            vis[temp.x][temp.y] = 1;
            if (G[temp.x][temp.y] == '@') cnt[temp.x * m + temp.y] += temp.step;
            que.push(temp);
        }
    }
}
int main() {
    Point st, ed;
    while (scanf("%d%d", &n, &m) != EOF) {
        for (int i = 0 ; i < n ; ++i) {
            getchar();
            scanf("%s", G[i]);
            for (int j = 0 ; j < m ; ++j) {
                if (G[i][j] == 'Y') st.x = i, st.y = j, st.step = 0;
                if (G[i][j] == 'M') ed.x = i, ed.y = j, ed.step = 0;
            }
        }
        solve(st);
        memset(vis, 0, sizeof(vis));
        solve(ed);
        memset(vis, 0, sizeof(vis));
        int ans = INF;
        for (int i = 0 ; i < n ; ++i) {
            for (int j = 0 ; j < m ; ++j) {
                if (G[i][j] == '@' && cnt[i * m + j] != 0) {
                    ans = min(ans, cnt[i * m + j]);
                }
            }
        }
        printf("%d
", ans * 11);
        memset(G, 0, sizeof(G));
        memset(cnt, 0, sizeof(cnt));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/WArobot/p/7922563.html