您的位置:首页 > 其它

POJ 2312 bfs

2017-08-24 00:00 471 查看
普通队列:
挺有趣的一道题目,然而很容易WA,我就WA了一次,虽然我Debug的时候已经知道哪里出问题了,就是比如说我搜到B和E时,从B搜第三个点,B左边的E就被搜了,step为3,然而其实他是step为2,
这里的处理方法很是巧妙,可以从B出发时,把B换成E,step+1,形成一个新的结点加入到队列中去.
之后,和杰哥交流了这下题,我对这个BFS又有了新的一点认识,BFS时,每次搜索的点,都要是同一级别的点,想这里B,和E就不是同一级别的点,所以将这个B,分成两部,注意B搜完后不要标记,B还没有访问完。
从这道题,我也对bfs有了更深的理解,“bfs之所以能最快找到最优解,就是因为它每次操作一步(这里的操作一步,很灵活,例如题目中的破坏砖墙),而while()里面的语句就是一次操作了!”

这道题中B点需要操作两步,所以遇到B点后不能+2后直接压进队列,需要在原地停一下,不能扩展到其他点,相当于他只能扩展到自身,所以就把自身压进队列里map[x][y]='E'是因为破坏砖墙一次就够了,不然下次,还是'B',不断压进队列,不断在原地停留

平常一般是考虑“入队列” 的点,这次要考虑“出队列” 的点是否满足条件!

普通队列

16ms

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>

#define LL long long
int const MAX = 1e6 + 1;
int const INF = 1 << 30;
double const EPS = 0.00000001;
using namespace std;

char g[303][303];
bool vis[303][303];
int n, m, ans;

struct Node {
int x, y, step;
Node(int x = 0, int y = 0, int step = 0) : x(x), y(y), step(step){}
};

Node st, ed;

void setVis(Node nd){
vis[nd.x][nd.y] = 1;
}

int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
int main(){
while (scanf("%d%d", &n, &m), n){
for (int i = 0; i < n; i++){
scanf("%s", g[i]);
for (int j = 0; j < m; j++){
if (g[i][j] == 'Y')
st.x = i, st.y = j, st.step = 0;
if (g[i][j] == 'T')
ed.x = i, ed.y = j;
}
}

memset(vis, 0, sizeof(vis));
queue<Node> q;
q.push(st);
setVis(st);
ans = -1;
while (!q.empty()){
Node nd = q.front();
q.pop();
if (nd.x == ed.x && nd.y == ed.y){
ans = nd.step;
break;
}
if (g[nd.x][nd.y] == 'B'){
q.push(Node(nd.x, nd.y, nd.step + 1));
g[nd.x][nd.y] = 'E';
continue;
}
for (int k = 0; k < 4; k++){
int nx = nd.x + dir[k][0], ny = nd.y + dir[k][1], ns = nd.step + 1;
if (nx < 0 || ny < 0 || nx >= n || ny >= m ||
vis[nx][ny] || g[nx][ny] == 'S' || g[nx][ny] == 'R') continue;
// if (g[nx][ny] == 'B') ns++;
Node t(nx, ny, ns);
q.push(t);
setVis(t);
}
}
printf("%d\n", ans);
}
return 0;
}


优先队列

注意优先队列和排序的比较函不一样(╯‵□′)╯︵┻━┻

16ms

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>

#define LL long long
int const MAX = 1e6 + 1;
int const INF = 1 << 30;
double const EPS = 0.00000001;
using namespace std;

char g[303][303];
bool vis[303][303];
int n, m, ans;

struct Node {
int x, y, step;
Node(int x = 0, int y = 0, int step = 0) : x(x), y(y), step(step){}
};

bool operator < (Node n1, Node n2){
return n1.step > n2.step;
}

Node st, ed;

void setVis(Node nd){
vis[nd.x][nd.y] = 1;
}

int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
int main(){
while (scanf("%d%d", &n, &m), n){
for (int i
3ff0
= 0; i < n; i++){
scanf("%s", g[i]);
for (int j = 0; j < m; j++){
if (g[i][j] == 'Y')
st.x = i, st.y = j, st.step = 0;
if (g[i][j] == 'T')
ed.x = i, ed.y = j;
}
}

memset(vis, 0, sizeof(vis));
priority_queue<Node> q;
q.push(st);
setVis(st);
ans = -1;
while (!q.empty()){
Node nd = q.top();
q.pop();
if (nd.x == ed.x && nd.y == ed.y){
ans = nd.step;
break;
}
for (int k = 0; k < 4; k++){
int nx = nd.x + dir[k][0], ny = nd.y + dir[k][1], ns = nd.step + 1;
if (nx < 0 || ny < 0 || nx >= n || ny >= m ||
vis[nx][ny] || g[nx][ny] == 'S' || g[nx][ny] == 'R') continue;
if (g[nx][ny] == 'B') ns++;
Node t(nx, ny, ns);
q.push(t);
setVis(t);
}
}
printf("%d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bfs 优先队列 搜索