题目链接

单向bfs就是水题

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int Max = + ;
struct Node
{
int x, y;
};
int g[Max][Max];
int vis[Max][Max];
int n, sx, sy, ex, ey;
int gx[] = {-, -, -, -, , , , };
int gy[] = {-, -, , , , , -, -};
bool in_bound(int x, int y)
{
if (x >= && y >= && x < n && y < n)
return true;
return false;
}
int bfs(int sx, int sy)
{
Node node, temp;
node.x = sx;
node.y = sy;
vis[sx][sy] = ;
queue<Node> q;
q.push(node);
while (!q.empty())
{
node = q.front();
q.pop();
if (node.x == ex && node.y == ey)
return vis[ex][ey];
for (int i = ; i < ; i++)
{
int fx = node.x + gx[i];
int fy = node.y + gy[i];
if (in_bound(fx, fy) && vis[fx][fy] > vis[node.x][node.y] + )
{
temp.x = fx;
temp.y = fy;
vis[fx][fy] = vis[node.x][node.y] + ;
q.push(temp);
}
}
}
return -;
}
int main()
{
int test;
scanf("%d", &test);
while (test--)
{
scanf("%d", &n);
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
memset(vis, INF, sizeof(vis));
printf("%d\n", bfs(sx, sy));
}
return ;
}

单向bfs

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

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

从这个博客学会的

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int Max = + ;
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[] = {-, -, -, -, , , , };
int gy[] = {-, -, , , , , -, -};
bool in_bound(int x, int y)
{
if (x >= && y >= && x < n && y < n)
return true;
return false;
}
int bfs()
{
if (sx == ex && sy == ey)
return ;
Node start, finish;
start.x = sx;
start.y = sy;
start.step = true;
finish.x = ex;
finish.y = ey;
finish.step = true;
vis[sx][sy] = ;
vis[ex][ey] = ;
queue<Node> frontSearch;
queue<Node> backSearch;
int fstep = , bstep = ;
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 = ; i < ; i++)
{
int fx = current.x + gx[i];
int fy = current.y + gy[i];
if (in_bound(fx, fy))
{
if (vis[fx][fy] == )
{
return fstep + bstep + ;
}
if (!vis[fx][fy])
{
vis[fx][fy] = ;
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 = ; i < ; i++)
{
int fx = current.x + gx[i];
int fy = current.y + gy[i];
if (in_bound(fx, fy))
{
if (vis[fx][fy] == )
{
return bstep + fstep + ;
}
if (!vis[fx][fy])
{
vis[fx][fy] = ;
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 -;
}
int main()
{
int test;
scanf("%d", &test);
while (test--)
{
scanf("%d", &n);
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
memset(vis, , sizeof(vis));
printf("%d\n", bfs());
}
return ;
}

第二种 双向bfs写法:

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int Max = + ;
struct Node
{
int x, y;
bool step;
};
int g[Max][Max];
int fvis[Max][Max], bvis[Max][Max];
int n, sx, sy, ex, ey;
int gx[] = {-, -, -, -, , , , };
int gy[] = {-, -, , , , , -, -};
bool in_bound(int x, int y)
{
if (x >= && y >= && x < n && y < n)
return true;
return false;
}
int bfs()
{
if (sx == ex && sy == ey)
return ;
Node start, finish;
start.x = sx;
start.y = sy;
start.step = true;
finish.x = ex;
finish.y = ey;
finish.step = true;
fvis[sx][sy] = ;
bvis[ex][ey] = ;
queue<Node> frontSearch;
queue<Node> backSearch;
int fstep = , bstep = ;
frontSearch.push(start);
backSearch.push(finish);
Node current;
while (!frontSearch.empty() || !backSearch.empty())
{
int frontSize = (int) frontSearch.size();
while (frontSize--) // 直接将这一个队 全都 拿出来更新,就相当于上一中的step一样,控制搜索的层次
{
current = frontSearch.front();
frontSearch.pop(); for (int i = ; i < ; i++)
{
int fx = current.x + gx[i];
int fy = current.y + gy[i];
if (in_bound(fx, fy))
{
if (bvis[fx][fy] != -) // 如果 倒着搜 已经搜到了,返回
return fvis[current.x][current.y] + + bvis[fx][fy];
if (fvis[fx][fy] == -) //否则正着+1
{
Node temp;
temp.x = fx;
temp.y = fy;
fvis[fx][fy] = fvis[current.x][current.y] + ;
frontSearch.push(temp);
}
}
}
}
int backSize = (int) backSearch.size();
while (backSize--)
{
current = backSearch.front();
backSearch.pop(); for (int i = ; i < ; i++)
{
int fx = current.x + gx[i];
int fy = current.y + gy[i];
if (in_bound(fx, fy))
{
if (fvis[fx][fy] != -)
{
return bvis[current.x][current.y] + + fvis[fx][fy];
}
if (bvis[fx][fy] == -)
{
Node temp;
temp.x = fx;
temp.y = fy;
bvis[fx][fy] = bvis[current.x][current.y] + ;
backSearch.push(temp);
}
}
}
}
}
return -;
}
int main()
{
int test;
scanf("%d", &test);
while (test--)
{
scanf("%d", &n);
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
memset(fvis, -, sizeof(fvis));
memset(bvis, -, sizeof(bvis));
printf("%d\n", bfs());
}
return ;
}

双向bfs 方法二

 

POJ1915Knight Moves(单向BFS + 双向BFS)的更多相关文章

  1. UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)

    题意 :w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...

  2. POJ 3126 Prime Path 解题报告(BFS & 双向BFS)

    题目大意:给定一个4位素数,一个目标4位素数.每次变换一位,保证变换后依然是素数,求变换到目标素数的最小步数. 解题报告:直接用最短路. 枚举1000-10000所有素数,如果素数A交换一位可以得到素 ...

  3. UVA - 1601 The Morning after Halloween (BFS/双向BFS/A*)

    题目链接 挺有意思但是代码巨恶心的一道最短路搜索题. 因为图中的结点太多,应当首先考虑把隐式图转化成显式图,即对地图中可以相互连通的点之间连边,建立一个新图(由于每步不需要每个鬼都移动,所以每个点需要 ...

  4. POJ1915 BFS&双向BFS

    俩月前写的普通BFS #include <cstdio> #include <iostream> #include <cstring> #include <q ...

  5. bfs(双向bfs加三维数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=2612 Find a way Time Limit: 3000/1000 MS (Java/Others)     ...

  6. BFS、双向BFS和A*

    BFS.双向BFS和A* Table of Contents 1. BFS 2. 双向BFS 3. A*算法 光说不练是无用的.我们从广为人知的POJ 2243这道题谈起:题目大意:给定一个起点和一个 ...

  7. 双向BFS和启发式搜索的应用

    题目链接 P5507 机关 题意简述   有12个旋钮,每个旋钮开始时处于状态 \(1\) ~ \(4\) ,每次操作可以往规定方向转动一个旋钮 (\(1\Rightarrow2\Rightarrow ...

  8. 洛谷 P1379 八数码难题(map && 双向bfs)

    题目传送门 解题思路: 一道bfs,本题最难的一点就是如何储存已经被访问过的状态,如果直接开一个bool数组,空间肯定会炸,所以我们要用另一个数据结构存,STL大法好,用map来存,直接AC. AC代 ...

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

    主题链接:Knight Moves 题意:8个方向的 马跳式走法 ,已知起点 和终点,求最短路 研究了一下双向BFS,不是非常难,和普通的BFS一样.双向BFS只是是从 起点和终点同一时候開始搜索,可 ...

随机推荐

  1. denounce函数:Javascript中如何应对高频触发事件

    在DOM Event的世界中,以scroll.resize.mouseover等为代表的高频触发事件显得有些与众不同.通常,DOM事件只有在明确的时间点才会被触发,比如被点击,比如XMLHttpReq ...

  2. ADO.NET 学习笔记 入门教程

    本文转载自:http://www.youarebug.com/forum.php?mod=viewthread&tid=57&page=1&extra=#pid63 这是本人在 ...

  3. 深入学习JavaScript(二)

    函数表达式和函数声明 函数声明 function 函数名(参数){函数体} 函数表达式 function 函数名(可选)(参数){函数体} 示例: function foo(){} // 声明,因为它 ...

  4. 转载:ZooKeeper Programmer's Guide(中文翻译)

    本文是为想要创建使用ZooKeeper协调服务优势的分布式应用的开发者准备的.本文包含理论信息和实践信息. 本指南的前四节对各种ZooKeeper概念进行较高层次的讨论.这些概念对于理解ZooKeep ...

  5. [BZOJ1143][CTSC2008]祭祀river(最长反链)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1143 分析: 最长反链==最小路径覆盖==n-二分图最大匹配数 某神犇对二分图的总结: ...

  6. android studio用法笔记

    1.每次创建新工程的时候,就会“check sdk repository”,然而这个进度条一动不动,解决方法:file>setting>plugins>sdk updater禁用就行 ...

  7. Maven的生命周期和插件

    首先解释下maven build等 Maven build是这个插件让你自己去配置执行目标的.Maven clean 清除上一次Maven执行的结果Maven generate-sources会根据p ...

  8. windows server2008 r2 下启用 sqlserver 2008的远程连接

    首先说明,本文转自互联网. TMD 花了二天,终于找到怎么开启这个远程连接了.....娘的,累死了,写下来,希望能帮助同胞们... 用win server 2008 r2 和sql server 20 ...

  9. 【转】css布局居中和CSS内容居中区别和对应DIV CSS代码

    原文地址:http://www.divcss5.com/jiqiao/j771.shtml css布局居中和CSS内容居中区别和对应DIV CSS代码教程与图文代码案例篇 对于新手来说DIV CSS布 ...

  10. Java发送邮件代码

    MailSenderInfo.java package com.nihaorz.mail.util; import java.util.Properties; public class MailSen ...