joj 2558 Ocean Currents 特别的广搜

题意:

  一个R*C的海面,1<= R、C<=1000,上面每个点都有八个方向之一的current,顺着流走一个单位cost 0,不顺着走一个单位cost 1。计算由一个初始位置到结束位置最小的cost.

思路:

  本来用A*,TLE,想想主要是因为A*考虑访问过的顶点,其实,这个题A*用的很憋屈,启发函数必须设成0。后来还是用了BFS,用两个队列,先把cost为0的全部入队列1,然后由队列1中的点扩展cost为1的点入队列2,直到队列1为空;再由队列2中点扩展cost为2的点,循环,直到找到目标节点。

  一般的BFS求最短路径,需要一个记录顶点路径长度的表,但是,这种用两个队列的方式,就不需要这个表,而只用一个变量即可。代码中,用两个指针来操作队列就可以了,内层循环结束了swap一下两个指针。

代码:

 

代码
   
     
#include < cstdio >
#include
< queue >
using namespace std;

struct position{
int x, y;
};

#define MAX 1000

int R, C;
char mt[MAX + 1 ][MAX + 4 ];
position S, T;
int move[ 8 ][ 2 ] = {{ - 1 , 0 }, { - 1 , 1 }, { 0 , 1 }, { 1 , 1 },
{
1 , 0 }, { 1 , - 1 }, { 0 , - 1 }, { - 1 , - 1 }};


bool is_valid( const position & v){
return ( 1 <= v.x && v.x <= R && 1 <= v.y && v.y <= C);
}

bool visited[MAX + 1 ][MAX + 1 ];
int BFS(){
for ( int i = 1 ; i <= R; ++ i)
for ( int j = 1 ; j <= C; ++ j)
visited[i][j]
= false ;
int dist, cur;
position u, v;
queue
< position > que1, que2;
queue
< position > * popen, * pnext;
dist
= 0 ;
popen
= & que1;
pnext
= & que2;

v
= S;
while (is_valid(v) && ! visited[v.x][v.y]){
if (v.x == T.x && v.y == T.y)
return dist;
popen
-> push(v);
visited[v.x][v.y]
= true ;
cur
= mt[v.x][v.y];
v.x
+= move[cur][ 0 ];
v.y
+= move[cur][ 1 ];
}
while ( true ){
++ dist;
while ( ! popen -> empty()){
u
= popen -> front();
popen
-> pop();
for ( int i = 0 ; i < 8 ; ++ i){
if (i == mt[u.x][u.y])
continue ;
v.x
= u.x + move[i][ 0 ];
v.y
= u.y + move[i][ 1 ];
while (is_valid(v) && ! visited[v.x][v.y]){
if (v.x == T.x && v.y == T.y)
return dist;
pnext
-> push(v);
visited[v.x][v.y]
= true ;
cur
= mt[v.x][v.y];
v.x
+= move[cur][ 0 ];
v.y
+= move[cur][ 1 ];
}
}
}
swap(popen, pnext);
}
}

int main(){
// freopen("in", "r", stdin);
while (scanf( " %d %d " , & R, & C) != EOF){
for ( int i = 1 ; i <= R; ++ i)
scanf(
" %s " , & mt[i][ 1 ]);
for ( int i = 1 ; i <= R; ++ i)
for ( int j = 1 ; j <= C; ++ j)
mt[i][j]
-= ' 0 ' ;
int m, d;
scanf(
" %d " , & m);
for ( int i = 0 ; i < m; ++ i){
scanf(
" %d %d %d %d " , & S.x, & S.y, & T.x, & T.y);
d
= BFS();
printf(
" %d\n " , d);
}
printf(
" \n " );
}
return 0 ;
}

 

 

你可能感兴趣的:(current)