A Za, A Za, Fighting...

坚信:勤能补拙

PKU 2312 Battle City (Cont.)

问题:
http://poj.org/problem?id=2312

思路:
http://www.cppblog.com/Joe/archive/2010/10/23/130973.html中,参考网上代码采用了一种"新"的BFS方法来解题,该方法的一个缺点在于每个点可能多次进入队列,这也直接导致了单个点的多次扩展

其实,这题可以采用原始的BFS方法来做,只是不能再用普通的队列,而需要使用优先级队列
通过这题,使我对于宽度优先搜索有了新的认识
普通的BFS之所以能够找到最小的步数,关键在于它是单步扩展的,也就是说它首先罗列出所有在一步之内可以到达的点,然后再罗列所有在两步之内可以到达的点,类似于"1-1-1...-2-2-2...-3-3-3..."的方式
这题在扩展的时候并非都是一步,所以普通的BFS并不能找出正确的解,例如:
Y B
E T
假如我们以右、下、左、上的顺序进行扩展,那么我们将得出结果是3,而事实上只需要2

优先级队列之所以能够找出正确解,是因为它保证我们始终从最小步数的点开始扩展

代码(C++)
 1 /* 0MS */
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<queue> /* priority queue */
 6 using namespace std;
 7 
 8 #define MAX_LEN 301
 9 #define is_valid(x, y) ((x)>=0 && (x)<M && (y)>=0 && (y)<N)
10 char map[MAX_LEN][MAX_LEN];
11 const int dx[] = {00-11};
12 const int dy[] = {-1100};
13 int M, N;
14 int you_x, you_y, target_x, target_y;
15 int visited[MAX_LEN][MAX_LEN];
16 struct Node {
17     int x, y;
18     int steps;
19     bool operator<(const Node &item) const {
20         return steps > item.steps;
21     }
22 }cur, next;
23 priority_queue<Node> states;
24 
25 int
26 bfs()
27 {
28     int i;
29     memset(visited, 0sizeof(visited));
30     while(!states.empty()) /* empty the queue */
31         states.pop();
32     next.x = you_x;
33     next.y = you_y;
34     next.steps = 0;
35     visited[you_x][you_y] = 1;
36     states.push(next);
37     while(!states.empty()) {
38         cur = states.top();
39         states.pop();
40         if(cur.x==target_x && cur.y==target_y)
41             return cur.steps;
42         for(i=0; i<4; i++) {
43             next.x = cur.x + dx[i];
44             next.y = cur.y + dy[i];
45             if(!visited[next.x][next.y]) {
46                 visited[next.x][next.y] = 1;
47                 if(map[next.x][next.y]=='E' || map[next.x][next.y]=='T') {
48                     next.steps = cur.steps+1;
49                     states.push(next);
50                 } else if(map[next.x][next.y]=='B') {
51                     next.steps = cur.steps+2;
52                     states.push(next);
53                 }
54             }
55         }
56     }
57     return -1;
58 }
59 
60 int
61 main(int argc, char **argv)
62 {
63     int i, j;
64     while(scanf("%d %d"&M, &N)!=EOF && M && N) {
65         for(i=0; i<M; i++) {
66             scanf("%s", map[i]);
67             for(j=0; j<N; j++) {
68                 if(map[i][j] == 'Y') {
69                     you_x = i;
70                     you_y = j;
71                 } else if(map[i][j] == 'T') {
72                     target_x = i; 
73                     target_y = j;
74                 }
75             }
76         }
77         printf("%d\n", bfs());
78     }
79 }

posted on 2010-10-23 20:10 simplyzhao 阅读(175) 评论(0)  编辑 收藏 引用 所属分类: B_搜索


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2010年9月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

统计

常用链接

留言簿(1)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜