#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
char mi[N][N];//迷宫矩阵
int dist1[N][N];//dist1 表示从起点到(i,j)的最短距离
int dist2[N][N];//dist2 表示从终点到(i,j)的最短距离
vector<pair<int, int>> water;//存储所有圣泉的横纵坐标
int dx[4] = {1,0,-1,0};
int dy[4] = {0,-1,0,1};
int n,m;
int start_x,start_y;//起点
int end_x,end_y;//终点
int E;//初始能量值
bool in_map(int x,int y)//判断合不合法
{
if(x <= 0 || y <= 0 || x > n || y > m)
{
return false;
}
if(mi[x][y] == '#')
{
return false;
}
return true;
}
void bfs(int x,int y,int dist[][N])
{
dist[x][y] = 0;//从起点到起点的距离为0
queue<pair<int , int>> q;
q.push({x,y});
while(!q.empty())
{
auto t = q.front();
q.pop();
for(int i = 0 ; i < 4; i++)
{
//取出当前坐标
int now_x = t.first;
int now_y = t.second;
//计算当前新的坐标
int new_x = now_x + dx[i];
int new_y = now_y + dy[i];
//要合法且访问,且最短距离可以更新
if(in_map(new_x,new_y) && dist[new_x][new_y] > dist[now_x][now_y]+1)
{
dist[new_x][new_y] = dist[now_x][now_y] + 1;//更新最短距离
q.push({new_x,new_y});
}
}
}
}
signed main()
{
//初始化为极大值
memset(dist1,0x3f,sizeof(dist1));
memset(dist2,0x3f,sizeof(dist2));
cin>>n>>m;
cin>>start_x>>start_y;
cin>>end_x>>end_y;
for(int i = 1 ; i <= n; i ++)
{
for(int j = 1 ; j <= m ; j ++)
{
cin>>mi[i][j];
if(mi[i][j] == 'V')
{
water.push_back({i,j});
}
}
}
cin>>E;
bfs(start_x,start_y,dist1);//从起点开始bfs,计算各点到起点的最小距离
bfs(end_x,end_y,dist2);//同理,终点
int step = dist1[end_x][end_y];//先取出起点到终点的距离
if(step <= E)//不大于能量值不需要用圣泉
{
cout<<step<<endl;
return 0;
}
step = 1e9;
for(int i = 0 ; i < water.size() ; i++)
{
int x = water[i].first;
int y = water[i].second;
if(dist1[x][y] <= E)//如果初始能量能到达圣泉
{
//从起点到达圣泉走dist1步,然后dist2步
//然后取小的更新
step = min(step,dist1[x][y] + dist2[x][y]);
}
}
if(step != 1e9)
{
//到达后,等step-E,再走step-E
cout<<E+(step-E)*2<<endl;
}
else cout<<"No"<<endl;
return 0;
}
混境之地4 bfs 最短路
最新推荐文章于 2024-07-25 11:27:31 发布