/* --------------------------------------------------------- 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 ; }