POJ1915Knight Moves(单向BFS + 双向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;
};
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)的更多相关文章
- UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)
题意 :w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...
- POJ 3126 Prime Path 解题报告(BFS & 双向BFS)
题目大意:给定一个4位素数,一个目标4位素数.每次变换一位,保证变换后依然是素数,求变换到目标素数的最小步数. 解题报告:直接用最短路. 枚举1000-10000所有素数,如果素数A交换一位可以得到素 ...
- UVA - 1601 The Morning after Halloween (BFS/双向BFS/A*)
题目链接 挺有意思但是代码巨恶心的一道最短路搜索题. 因为图中的结点太多,应当首先考虑把隐式图转化成显式图,即对地图中可以相互连通的点之间连边,建立一个新图(由于每步不需要每个鬼都移动,所以每个点需要 ...
- POJ1915 BFS&双向BFS
俩月前写的普通BFS #include <cstdio> #include <iostream> #include <cstring> #include <q ...
- bfs(双向bfs加三维数组)
http://acm.hdu.edu.cn/showproblem.php?pid=2612 Find a way Time Limit: 3000/1000 MS (Java/Others) ...
- BFS、双向BFS和A*
BFS.双向BFS和A* Table of Contents 1. BFS 2. 双向BFS 3. A*算法 光说不练是无用的.我们从广为人知的POJ 2243这道题谈起:题目大意:给定一个起点和一个 ...
- 双向BFS和启发式搜索的应用
题目链接 P5507 机关 题意简述 有12个旋钮,每个旋钮开始时处于状态 \(1\) ~ \(4\) ,每次操作可以往规定方向转动一个旋钮 (\(1\Rightarrow2\Rightarrow ...
- 洛谷 P1379 八数码难题(map && 双向bfs)
题目传送门 解题思路: 一道bfs,本题最难的一点就是如何储存已经被访问过的状态,如果直接开一个bool数组,空间肯定会炸,所以我们要用另一个数据结构存,STL大法好,用map来存,直接AC. AC代 ...
- POJ 1915-Knight Moves (单向BFS && 双向BFS 比)
主题链接:Knight Moves 题意:8个方向的 马跳式走法 ,已知起点 和终点,求最短路 研究了一下双向BFS,不是非常难,和普通的BFS一样.双向BFS只是是从 起点和终点同一时候開始搜索,可 ...
随机推荐
- sprintf_s的教训
sprintf_s 是个比sprintf更安全的函数,今天在使用的过程中犯了个错误,代码的大致意思如下 void Test_sprintf_s() { ]; memset(buff, , sizeof ...
- 数学符号“s.t.”的意义
在优化问题的求解中,如线性规划.非线性规划问题等,经常会遇到数学符号“s.t.”,它的意思是什么呢? “s.t.”,指 subject to,受限制于.... 例如: 目标函数:min {x+2} 约 ...
- 【jQuery】Jquery.cookie()
注意:如果不设置path,默认为当前路径,新建cookie $.cookie('name', 'value'); 新建带限制时间cookie $.cookie('name', 'value', { e ...
- 我的第一个DMZ方案实践
方案提出的初衷:外网需要定时和不定时推送数据到内网服务器(只要求数据到达内网,没有要求直接连接到内网) 为什么不是直连到内网:每个人第一想到的是不安全,是的,没错不安全.内网的应用和外网的应用最明显的 ...
- Java--剑指offer(9)
41.输出所有和为S的连续正数序列.序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序 import java.util.ArrayList; public class Solution { ...
- 【转】深入浅出Java三大框架SSH与MVC的设计模式
原文链接:http://www.cnblogs.com/itao/archive/2011/08/22/2148844.html 在许许多多的初学者和程序员,都在趋之若鹜地学习Web开发的宝典级框架: ...
- git组成结构
1. blob对象(blob) 2. 目录树(tree) 3. 提交(commit) 4. 标签(tag) git 文件按照状态分为3类: 1. 已追踪的(tracked) 2. 被忽略的(Ignor ...
- react 属性与状态 学习笔记
知识点:1.react 属性的调用 this.props.被调用的属性名 设置属性的常用方法:var props = { one: '123', two: 321}调用这个属性:<HelloWo ...
- 172C
模拟 #include<iostream> #include<algorithm> #include<vector> #include<cstdio> ...
- thinkphp框架中“关联操作”的完整定义详解
在复杂的关联操作中,如果要给关联定义增加可选的属性,我们可以采用完整定义的方式. 完整定义的格式是: protected $_link = array( '关联表名1' => arr ...