题目描述
今天LZY攻城小分队出动了,他们需要在尽可能短的时间内攻占敌人的大本营。战场是一个n * m的二维网格,LZY小分队初始在(0,0)点,敌军大本营在( n -1 ,m - 1)点,每个点上有一个对应的数字代表LZY小分队攻占这个据点需要耗费的时间,现在作为LZY小分队的指挥官,你需要指定一条合适的路线,使LZY小分队能用最短的时间攻占敌人大本营。
输入
测试样例由多组测试数据组成。
每组测试数据第一行输入两个正整数n , m ( 1 <= n,m <= 100)
接下来输入n * m 个数字 ,每个数字不超过 500
输出
输出LZY小分队攻占敌人大本营所需要的最短时间
样例输入
3 3
1 2 3
1 2 3
1 2 3
样例输出
8
总结:只要会优先队列再结合BFS就能写这一题了。
代码
#include<bits/stdc++.h>
using namespace std;
#define maxn 105
int n,m,ans,s[maxn][maxn];
int dir[4][2]={1,0,-1,0,0,1,0,-1}; //方向二维数组
bool vis[maxn][maxn]; //标记
struct num{
int x,y,step;
};
struct cmp{
bool operator()(num a,num b){//优先队列与实际排序相反
return a.step>b.step;
}
};
priority_queue<num,vector<num>,cmp> q;//优先队列创建
void bfs(){
while(!q.empty()){
int len=q.size();
for(int i=0;i<len;i++){
int xx=q.top().x;
int yy=q.top().y;
int step1=q.top().step;
q.pop();
if(xx==n-1&&yy==m-1){ //判断是否到终点
ans=step1;
return;
}
for(int j=0;j<4;j++){
int fx=xx+dir[j][0];
int fy=yy+dir[j][1];
if(fx>=0&&fx<n&&fy>=0&&fy<m&&!vis[fx][fy]){//判断是否走过
vis[fx][fy]=1;
q.push({fx,fy,step1+s[fx][fy]});//压入队列
}
}
}
}
return;
}
int main(){
while(cin>>n>>m){
ans=0;
while(!q.empty()){
q.pop();
}//清空队列中的残念
memset(vis,0,sizeof(vis));//初始化数组
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>s[i][j];
}
}
vis[0][0]=1;
q.push({0,0,s[0][0]});//压入队列
bfs();
cout<<ans<<endl; //输出答案
}
return 0;