#include <bits/stdc++.h>
using namespace std;
int m, n;
int a[1001][1001];//记录地图
bool b[1001][1001];//此点是否被访问
int c[1001][1001];//通过地图的坐标,记录公主到灌木丛,再到骑士的距离之和
int x, y;//公主坐标
int x1, y11;//骑士坐标
int sum,sum1;//记录灌木丛的长度用
struct point
{
int x, y;
int length;
};
int p1 = 0;
int dx[] = { 0,0,1,-1 };
int dy[] = { 1,-1,0,0 };
int main()
{
cin >> m >> n;
for (int i = 1;i <= n;i++)
for (int j = 1;j <= m;j++)
{
cin >> a[i][j];
if (a[i][j] == 2)x = j, y = i;
if (a[i][j] == 3)x1 = j, y11 = i;
if (a[i][j] == 4)sum++;
}
queue<point> s1;
queue<point> s2;
s1.push({ x,y,0});
while (s1.size())//从公主开始做BFS,直至获取到达所以灌木丛的最短距离
{
int x2 = s1.front().x,
y2 = s1.front().y,
length2=s1.front().length;
b[y2][x2] = 1;
if (a[y2][x2]==4)
{
s2.push(s1.front());
c[y2][x2] = s1.front().length;
sum1++;
if (sum == sum1)break;//获得全部的灌木路径,就退出
}
for (int i = 0;i < 4;i++)
{
if (x2 + dx[i] >= 1 && x2 + dx[i] <= m && y2 + dy[i] >= 1 && y2 + dy[i] <= n && !b[y2 + dy[i]][x2 + dx[i]]&&a[y2 + dy[i]][x2 + dx[i]]!=1&& a[y2 + dy[i]][x2 + dx[i]] != 3)
s1.push({ x2 + dx[i] ,y2 + dy[i] ,length2 + 1 });
}
s1.pop();
}
sum1 = 0;
queue<point> s3;//从骑士出发,找到各个灌木丛距离骑士的距离。将这些长度与之前求得的公主到每个灌木丛的距离相加,即可得出所有灌木丛条件下的长度
s3.push({ x1,y11,0 });
memset(b, 0, sizeof(b));
while (s3.size())
{
int x2 = s3.front().x,
y2 = s3.front().y,
length2 = s3.front().length;
b[y2][x2] = 1;
if (a[y2][x2] == 4)
{
c[y2][x2]+= s3.front().length;
sum1++;
if (sum == sum1)break;//获得全部的灌木路径,就退出
}
for (int i = 0;i < 4;i++)
{
if (x2 + dx[i] >= 1 && x2 + dx[i] <= m && y2 + dy[i] >= 1 && y2 + dy[i] <= n && !b[y2 + dy[i]][x2 + dx[i]] && a[y2 + dy[i]][x2 + dx[i]] != 1)
s3.push({ x2 + dx[i] ,y2 + dy[i] ,length2 + 1 });
}
s3.pop();
}
int min1 = 0x7fffffff;
for (int i = 1;i <= sum;i++)//比较长度
{
min1 = min(min1, c[s2.front().y][s2.front().x]);
s2.pop();
}
cout << min1;
}
只对了2个其它的不是爆内存就是错误,请大佬指正