双向BFS

/*转自http://blog.csdn.net/custqi/article/details/6455425感觉对双向广搜写得挺清楚的*/

 1 #include<iostream>
 2 #include<cmath>
 3 #include<queue>
 4 using namespace std;
 5 const int maxn = 301;
 6 int n;
 7 int used[maxn][maxn];
 8 int g[maxn][maxn];
 9 int d[8][2] = { {-2,-1}, {-2,1}, {-1,-2}, {-1,2}, {1,-2}, {1,2}, {2,-1}, {2,1} };
10 //int x[] = {-2,-2,-1,-1,1,1,2,2};
11 //int y[] = {-1,1,-2,2,-2,2,-1,1};
12 struct Point
13 {
14     int x,y;
15 }st,ed;
16 int Check(int x,int y)
17 {
18     return (x>=0 && x<n && y>=0 &&y<n);
19 }
20 int solve()
21 {
22     int sx,sy,tx,ty; //sx,sy 先前结点 tx,ty生成新结点
23     queue<Point>Q;
24     Point curNode,nextNode;
25     memset(used,0,sizeof(used));
26     //放入起始结点
27     g[st.x][st.y] = 0;
28     used[st.x][st.y] = 1;//由起始结点方向扩展的结点记录值为 1
29     Q.push(st);
30     //放入终止结点
31     g[ed.x][ed.y] = 0;
32     used[ed.x][ed.y] = 2;//由终止结点方向扩展的结点记录值为 2
33     Q.push(ed);
34     //同时放入起始结点和终止结点 进行双向广搜
35     while(!Q.empty())
36     {
37         curNode = Q.front();
38         Q.pop();
39         sx = curNode.x;
40         sy = curNode.y;
41         for(int i=0;i<8;i++)
42         {
43             tx = sx + d[i][0];
44             ty = sy + d[i][1];
45             if(!Check(tx,ty)) continue;
46             if(used[tx][ty]==0)    //如果used[tx][ty]未访问过
47             {
48                 g[tx][ty] = g[sx][sy]+1; //更新在tx ty的值
49                 nextNode.x = tx;
50                 nextNode.y = ty;
51                 used[tx][ty] = used[sx][sy]; //
52                 Q.push(nextNode);
53             }
54             else if(used[sx][sy]!=used[tx][ty])    //起始方向与终止方向同时进行后,此时的结点为俩个方向相遇的点,得到结果
55             {
56                 return g[sx][sy] + g[tx][ty] + 1;
57             }
58         }
59     }
60     return 0;
61 }
62 int main()
63 {
64     int TestCases;
65     scanf("%d",&TestCases);
66     while(TestCases--)
67     {
68         scanf("%d%d%d%d%d",&n,&st.x,&st.y,&ed.x,&ed.y);
69         printf("%d/n",solve());
70     }
71     return 0;
72 }
时间: 2024-12-18 04:47:22

双向BFS的相关文章

Hdu1401-Solitaire(双向bfs)

Solitaire is a game played on a chessboard 8x8. The rows and columns of the chessboard are numbered from 1 to 8, from the top to the bottom and from left to right respectively.There are four identical pieces on the board. In one move it is allowed to

UVA-1604 Cubic Eight-Puzzle (双向BFS+状态压缩+限制搜索层数)

题目大意:立体的八数码问题,一次操作是滚动一次方块,问从初始状态到目标状态的最少滚动次数. 题目分析:这道题已知初始状态和目标状态,且又状态数目庞大,适宜用双向BFS.每个小方块有6种状态,整个大方格有9*6^8个状态.每个小方块用一位6进制数表示即可. 注意:状态转移时要谨慎,否则会出现意想不到的错误: 这道题的末状态有256(2^8)个,如果对搜索层数不加限制,即使双向BFS也会TLE的,当限制正向搜索15层逆向搜索15层至正向搜索27层反向搜索3层时都能AC(我下面贴出的程序是这样的),其

HDU1195 双向BFS(或BFS)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1195 , 双向BFS或者直接BFS也可以过. 其实这道题只是单向BFS就可以过的,但是为了练算法,所以还是用了双向BFS来写. 算法: 先预处理一下,从1111到9999的所有点进行构图(由于是1~9的,所以除去含有0元素的数字),能进行一次变换变成的数字则表示两点之间连通.然后从初态与目态两个点进行BFS,如果有轨迹重合的就返回路程和. 这里注意双向BFS要一层一层的进行搜索,不然的话会产生错误,

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

BFS、双向BFS和A*

BFS.双向BFS和A* Table of Contents 1. BFS 2. 双向BFS 3. A*算法 光说不练是无用的.我们从广为人知的POJ 2243这道题谈起:题目大意:给定一个起点和一个终点.按骑士的走法(走日字),从起点到终点的最少移动多少次 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2RraXJjaGhvZmY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/g

HDU 1043 Eight(双向BFS+康托展开)

http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用双向BFS来做. ①双向BFS 在单向BFS的基础上,多建一个从终止状态开始搜索的队列,当然这个时候需要两个vis[]辅助数组,分别记录两个队列的访问情况,当两个队列相遇时即可终止循环. ②康托展开 X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[

POJ 1915-Knight Moves (单向BFS &amp;&amp; 双向BFS 比较)

题目链接:Knight Moves 研究了一下双向BFS,不是很难,和普通的BFS一样,双向BFS不过是从 起点和终点同时开始搜索,可减少搜索时间 当两条搜索路线相遇时,结束. 貌似有一年百度的招聘 笔试,就是双向BFS.... 下面,比较一下BFS 和 双向BFS的用时: BFS STL的queue可能会浪费一点时间 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstrin

第六章部分例题 双向bfs邻接表和邻接矩阵实现

Idealpath 双向bfs输出颜色,邻接矩阵实现 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <map> 6 #include <algorithm> 7 8 using namespace std; 9 10 const int maxn=10000; 11 const int inf=1

[NOIP2002]字串变换 T2 双向BFS

题目描述 已知有两个字串  A,B  及一组字串变换的规则(至多6个规则): A1?>B1 A2?>B2 规则的含义为:在  A$中的子串  A1可以变换为可以变换为B1.A2可以变换为可以变换为B2  -. 例如:A==′abcd′B='xyz' 变换规则为: 'abc'-> 'xu' 'ud'-> 'y' 'y'-> 'yz' 则此时,A可以经过一系列的变换变为可以经过一系列的变换变为B,其变换的过程为: 'abcd'-> 'xud'-> 'xy'->

Colour Hash (Uva 704 双向bfs)

Colour Hash Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description This puzzle consists of two wheels. Both wheels can rotate both clock and counter-clockwise. They contain 21 coloured pieces, 10 of which