UVA11573 Ocean Currents
分析
无边权,最短路,一眼BFS。
两种情况。
1.随波逐流。不消耗能量,代价为
0
0
0。
2.逆流而上。随意移动到相邻格子,消耗能量,代价为
1
1
1。
出现了不同的代价,如何处理?
BFS的一个重要性质,当边权固定时,一个点第一次被遍历到的代价为最小,也就是说保证队列的队头是队列中最小的。
这是什么?
优先队列
其实当只有两种权值时,双端队列的效果类似,但是优先队列更具有普遍性。
所以,可以将BFS中的普通队列改为优先队列,然后分成上述两种情况搜索,问题解决。
#include<bits/stdc++.h>
#define endl putchar('\n')
using namespace std;
const int M=1e3+5;
void print(int x){
if(x<0)putchar('-'),x=-x;
if(x<10){putchar(x+'0');return;}
print(x/10);
putchar(x%10+'0');
}
int n,m;
int T;
int a[M][M];
int x,y,r,c;
struct node{
int x,y,dis;
bool friend operator<(node a,node b){
return a.dis>b.dis;
}
};
int vis[M][M];
int dis[M][M];
int dx[8]={-1,-1,0,1,1,1,0,-1};
int dy[8]={0,1,1,1,0,-1,-1,-1};
void bfs(){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
vis[i][j]=0;
}
}
priority_queue<node>q;
q.push(node{x,y,0});
vis[x][y]=1;
dis[x][y]=0;
while(!q.empty()){
node p=q.top();
q.pop();
if(p.x==r&&p.y==c){
print(p.dis);
return;
}
for(int i=0;i<8;i++){
int xx=p.x+dx[i];
int yy=p.y+dy[i];
if(xx<1||yy<1||xx>n||yy>m||(vis[xx][yy]&&dis[xx][yy]<=p.dis+1))continue;
dis[xx][yy]=p.dis+1;
vis[xx][yy]=1;
q.push(node{xx,yy,p.dis+1});
}
int imsb=a[p.x][p.y];
int xx=p.x+dx[imsb];
int yy=p.y+dy[imsb];
if(xx<1||yy<1||xx>n||yy>m||(vis[xx][yy]&&dis[xx][yy]<=p.dis))continue;
dis[xx][yy]=p.dis;
q.push(node{xx,yy,p.dis});
}
}
signed main(){
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
char w;
cin>>w;
a[i][j]=w-'0';
}
}
cin>>T;
while(T--){
cin>>x>>y>>r>>c;
bfs();
endl;
}
}
浙公网安备 33010602011771号