#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 2E2 + 10;
const int INF = 0x3f3f3f3f;
const int dir[][2] = {1, 0, 0, 1, -1, 0, 0, -1};
int n, m, mp[maxn][maxn][2], dis[maxn][maxn][2];
char str[maxn][maxn];
struct Node
{
int x, y, step;
bool in(int flag)
{
return (x >= 0 && x < n && y >= 0 && y < m && str[x][y] != '#' && mp[x][y][flag] == 0);
}
};
void bfs(int x, int y, int flag)
{
queue<Node>Q;
Node Cur, Next;
Cur.x = x; Cur.y = y; Cur.step = 0;
mp[x][y][flag] = 1;
Q.push(Cur);
while (!Q.empty())
{
Cur = Q.front(); Q.pop();
Next.step = Cur.step + 1;
for (int i = 0; i < 4; i++)
{
Next.x = Cur.x + dir[i][0];
Next.y = Cur.y + dir[i][1];
if (Next.in(flag))
{
mp[Next.x][Next.y][flag] = 1;
if (str[Next.x][Next.y] == '@')
dis[Next.x][Next.y][flag] = Next.step;
Q.push(Next);
}
}
}
}
int main(int argc, char const *argv[])
{
while (~scanf("%d%d", &n, &m) && m + n)
{
int ans = INF;
memset(dis, INF, sizeof(dis));
memset(mp, 0, sizeof(mp));
for (int i = 0; i < n; i++)
scanf("%s", str[i]);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
{
if (str[i][j] == 'Y')
bfs(i, j, 0);
else if (str[i][j] == 'M')
bfs(i, j, 1);
}
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (str[i][j] == '@')
ans = min(dis[i][j][0] + dis[i][j][1], ans);
printf("%d\n", ans * 11);
}
return 0;
}
两个源点,多个汇点的最短路,用bfs就可以,虽然我觉得这个题目应该放在图论里。。。