题意:给出两个初始地点Y,M,还有几个终点@。要求两个初始点到这些终点的最少步数之和的最小数。
解题思路:两遍bfs,给kfc所在地加一个量用res[i][j][k]表示,k=0是Y到(i,j)的最少步数,k=1是M到(i,j)的最少步数。
最后遍历地图找到和最少的。
代码如下:
#include<cstdio>
#include<queue>
#include<cstdlib>
using namespace std;
const int inf = 0x3f3f3f3f;
char map[205][205];
int vis[205][205],res[205][205][5];//res用来存每一遍bfs最短路的长度
int n, m;
struct node {
int a, b;
int step;
};
node Y, M;
int dir[4][2] = { {1,0},{0,1},{-1,0},{0,-1} };
bool check(int x, int y)
{
if (x < 0 || x >= n || y < 0 || y >= m || vis[x][y] || map[x][y] == '#')
return 0;
return 1;
}
void bfs(node t, int num)
{
queue<node>q;
q.push(t);
memset(vis, 0, sizeof(vis));
vis[t.a][t.b] = 1;
node cur, next;
while (!q.empty())
{
cur = q.front();
q.pop();
if (map[cur.a][cur.b] == '@')
{
res[cur.a][cur.b][num] = cur.step;
}
for (int i = 0;i < 4;i++)
{
next.a = cur.a + dir[i][0];
next.b = cur.b + dir[i][1];
next.step = cur.step + 1;
if (check(next.a, next.b))
{
vis[next.a][next.b] = 1;
q.push(next);
}
}
}
}
int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = 0;i < n;i++)
{
scanf("%s", map[i]);
for (int j = 0;j < m;j++)
{
if (map[i][j] == 'Y')
{
Y.a = i;
Y.b = j;
Y.step = 0;
}
else if (map[i][j] == 'M')
{
M.a = i;
M.b = j;
M.step = 0;
}
}
}
memset(res, 0, sizeof(res));
bfs(Y, 0);
bfs(M, 1);
int ans = inf;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if (res[i][j][0] && res[i][j][1])
{
ans = min(ans, res[i][j][0] + res[i][j][1]);
}
printf("%d\n", ans * 11);
}
return 0;
}