POJ1915Knight Moves(单向BFS + 双向BFS)

题目链接

单向bfs就是水题

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <queue>
 6 using namespace std;
 7 const int INF = 0x3f3f3f3f;
 8 const int Max = 300 + 5;
 9 struct Node
10 {
11     int x, y;
12 };
13 int g[Max][Max];
14 int vis[Max][Max];
15 int n, sx, sy, ex, ey;
16 int gx[8] = {-1, -2, -2, -1, 1, 2, 2, 1};
17 int gy[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
18 bool in_bound(int x, int y)
19 {
20     if (x >= 0 && y >= 0 && x < n && y < n)
21         return true;
22     return false;
23 }
24 int bfs(int sx, int sy)
25 {
26     Node node, temp;
27     node.x = sx;
28     node.y = sy;
29     vis[sx][sy] = 0;
30     queue<Node> q;
31     q.push(node);
32     while (!q.empty())
33     {
34         node = q.front();
35         q.pop();
36         if (node.x == ex && node.y == ey)
37             return vis[ex][ey];
38         for (int i = 0; i < 8; i++)
39         {
40             int fx = node.x + gx[i];
41             int fy = node.y + gy[i];
42             if (in_bound(fx, fy) && vis[fx][fy] > vis[node.x][node.y] + 1)
43             {
44                 temp.x = fx;
45                 temp.y = fy;
46                 vis[fx][fy] = vis[node.x][node.y] + 1;
47                 q.push(temp);
48             }
49         }
50     }
51     return -1;
52 }
53 int main()
54 {
55     int test;
56     scanf("%d", &test);
57     while (test--)
58     {
59         scanf("%d", &n);
60         scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
61         memset(vis, INF, sizeof(vis));
62         printf("%d\n", bfs(sx, sy));
63     }
64     return 0;
65 }
单向bfs

 

做这题主要是学着写双向bfs;

分别从起点和终点开始搜,如果重合即找到

从这个博客学会的

 

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int Max = 300 + 5;
struct Node
{
    int x, y;
    bool step;
};
// 这个step的意思之前没搞明白,他其实就是指的 在某一步下可以走到点
//开始讲 start.step设为true,因此在只能走一次 8 个点,然后8个点都是第一步走的,然后把最后一个点的step设为true,当你走第二部时候,就是 do { 以这个点扩展 8 步} while ( !current.step) step控制了层数。 
int g[Max][Max];
int vis[Max][Max];
int n, sx, sy, ex, ey;
int gx[8] = {-1, -2, -2, -1, 1, 2, 2, 1};
int gy[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
bool in_bound(int x, int y)
{
    if (x >= 0 && y >= 0 && x < n && y < n)
        return true;
    return false;
}
int bfs()
{
    if (sx == ex && sy == ey)
        return 0;
    Node start, finish;
    start.x = sx;
    start.y = sy;
    start.step = true;
    finish.x = ex;
    finish.y = ey;
    finish.step = true;
    vis[sx][sy] = 1;
    vis[ex][ey] = 2;
    queue<Node> frontSearch;
    queue<Node> backSearch;
    int fstep = 0, bstep = 0;
    frontSearch.push(start);
    backSearch.push(finish);
    Node current;
    while (!frontSearch.empty() || !backSearch.empty())
    {
        if (!frontSearch.empty())
        {
            do
            {
                current = frontSearch.front();
                frontSearch.pop();
                for (int i = 0; i < 8; i++)
                {
                    int fx = current.x + gx[i];
                    int fy = current.y + gy[i];
                    if (in_bound(fx, fy))
                    {
                        if (vis[fx][fy] == 2)
                        {
                            return fstep + bstep + 1;
                        }
                        if (!vis[fx][fy])
                        {
                            vis[fx][fy] = 1;
                            Node temp;
                            temp.x = fx;
                            temp.y = fy;
                            temp.step = false;
                            frontSearch.push(temp);
                        }
                    }
                }
            }while(current.step == false);
            fstep++;
            current = frontSearch.front();
            frontSearch.pop();
            current.step = true;  // 为了让最后队列中最后一个数step为true,先将队首拿出来,修改step,然后在入队
            frontSearch.push(current);
        }

        if (!backSearch.empty())
        {
            do
            {
                current = backSearch.front();
                backSearch.pop();
                for (int i = 0; i < 8; i++)
                {
                    int fx = current.x + gx[i];
                    int fy = current.y + gy[i];
                    if (in_bound(fx, fy))
                    {
                        if (vis[fx][fy] == 1)
                        {
                            return bstep + fstep + 1;
                        }
                        if (!vis[fx][fy])
                        {
                            vis[fx][fy] = 2;
                            Node temp;
                            temp.x = fx;
                            temp.y = fy;
                            temp.step = false;
                            backSearch.push(temp);
                        }
                    }
                }
            } while(current.step == false);
            bstep++;
            current = backSearch.front();
            backSearch.pop();
            current.step = true;
            backSearch.push(current);
        }
    }
    return -1;
}
int main()
{
    int test;
    scanf("%d", &test);
    while (test--)
    {
        scanf("%d", &n);
        scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
        memset(vis, 0, sizeof(vis));
        printf("%d\n", bfs());
    }
    return 0;
}

 

第二种 双向bfs写法:

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <algorithm>
  5 #include <queue>
  6 using namespace std;
  7 const int INF = 0x3f3f3f3f;
  8 const int Max = 300 + 5;
  9 struct Node
 10 {
 11     int x, y;
 12     bool step;
 13 };
 14 int g[Max][Max];
 15 int fvis[Max][Max], bvis[Max][Max];
 16 int n, sx, sy, ex, ey;
 17 int gx[8] = {-1, -2, -2, -1, 1, 2, 2, 1};
 18 int gy[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
 19 bool in_bound(int x, int y)
 20 {
 21     if (x >= 0 && y >= 0 && x < n && y < n)
 22         return true;
 23     return false;
 24 }
 25 int bfs()
 26 {
 27     if (sx == ex && sy == ey)
 28         return 0;
 29     Node start, finish;
 30     start.x = sx;
 31     start.y = sy;
 32     start.step = true;
 33     finish.x = ex;
 34     finish.y = ey;
 35     finish.step = true;
 36     fvis[sx][sy] = 0;
 37     bvis[ex][ey] = 0;
 38     queue<Node> frontSearch;
 39     queue<Node> backSearch;
 40     int fstep = 0, bstep = 0;
 41     frontSearch.push(start);
 42     backSearch.push(finish);
 43     Node current;
 44     while (!frontSearch.empty() || !backSearch.empty())
 45     {
 46         int frontSize = (int) frontSearch.size();
 47         while (frontSize--)  // 直接将这一个队 全都 拿出来更新,就相当于上一中的step一样,控制搜索的层次
 48         {
 49             current = frontSearch.front();
 50             frontSearch.pop();
 51            
 52             for (int i = 0; i < 8; i++)
 53             {
 54                 int fx = current.x + gx[i];
 55                 int fy = current.y + gy[i];
 56                 if (in_bound(fx, fy))
 57                 {
 58                     if (bvis[fx][fy] != -1)  // 如果 倒着搜 已经搜到了,返回
 59                         return fvis[current.x][current.y] + 1 + bvis[fx][fy];
 60                     if (fvis[fx][fy] == -1) //否则正着+1
 61                     {
 62                         Node temp;
 63                         temp.x = fx;
 64                         temp.y = fy;
 65                         fvis[fx][fy] = fvis[current.x][current.y] + 1; 
 66                         frontSearch.push(temp);
 67                     }
 68                 }
 69             }
 70         }
 71         int backSize = (int) backSearch.size();
 72         while (backSize--)
 73         {
 74             current = backSearch.front();
 75             backSearch.pop();
 76            
 77             for (int i = 0; i < 8; i++)
 78             {
 79                 int fx = current.x + gx[i];
 80                 int fy = current.y + gy[i];
 81                 if (in_bound(fx, fy))
 82                 {
 83                     if (fvis[fx][fy] != -1)
 84                     {
 85                         return bvis[current.x][current.y] + 1 + fvis[fx][fy];
 86                     }
 87                     if (bvis[fx][fy] == -1)
 88                     {
 89                         Node temp;
 90                         temp.x = fx;
 91                         temp.y = fy;
 92                         bvis[fx][fy] = bvis[current.x][current.y] + 1;
 93                         backSearch.push(temp);
 94                     }
 95                 }
 96             }
 97         }
 98     }
 99     return -1;
100 }
101 int main()
102 {
103     int test;
104     scanf("%d", &test);
105     while (test--)
106     {
107         scanf("%d", &n);
108         scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
109         memset(fvis, -1, sizeof(fvis));
110         memset(bvis, -1, sizeof(bvis));
111         printf("%d\n", bfs());
112     }
113     return 0;
114 }
双向bfs 方法二

 

 

 

posted @ 2016-03-31 21:22  zhaop  阅读(279)  评论(0编辑  收藏  举报