bfs

bfs=队列

队列的操作

头文件

#include<deque>

声明方法:

1、普通声明

queue<int>q;

2、结构体

    struct node
{
int x, y;
};
queue<node>q;

操作(假设已经定义队列为q)

q.empty() 如果队列为空返回真
q.pop() 删除对顶元素
q.push() 加入一个元素
q.size() 返回优先队列中拥有的元素个数
q.top() 返回优先队列对顶元素

优先队列

优先队列容器与队列一样,只能从队尾插入元素,从队首删除元素。但是它有一个特性,就是队列中最大的元素总是位于队首,所以出队时,并非按照先进先出的原则进行,而是将当前队列中最大的元素出队。这点类似于给队列里的元素进行了由大互小的顺序排序。元素的比较规则默认按元素值由大到小排序,可以重载“<”操作符来重新定义比较规则。
声明方式:
1、普通方法:

priority_queue<int>q;   //通过操作,按照元素从大到小的顺序出队
priority_queue<int,vector<int>, greater<int> >q; //通过操作,按照元素从小到大的顺序出队

2、自定义优先级:

    struct cmp {
  operator bool ()(int x, int y)
  {
     return x > y; // x小的优先级高 //也可以写成其他方式,如: return p[x] > p[y];表示p[i]小的优先级高
  }
};
priority_queue<int, vector<int>, cmp>q; //定义方法
//其中,第二个参数为容器类型。第三个参数为比较函数。

3、结构体声明方式:

    struct node {
  int x, y;
  friend bool operator < (node a, node b)
  {
    return a.x > b.x; //结构体中,x小的优先级高
  }
};
priority_queue<node>q; //定义方法
//在该结构中,y为值, x为优先级。
//通过自定义operator<操作符来比较元素中的优先级。
//在重载”<”时,最好不要重载”>”,可能会发生编译错误

bfs   由近到远的扩散过程

**例题**

一个长方形的房间,铺着方砖,每块砖是 #或黑点. 。
一个人站在黑砖上,可以按上、下、左、右方向移动到相邻的砖。
他不能在#上移动,他只能在黑砖上移动。
起点是@,要求:遍历所有黑点。

 
(a)1进队列。当前队列是{1}。
(b)1出队,1的邻居2, 3进队。当前队列{2, 3}。
 (可以理解为:从1扩散到2、3。)
(c)2出队,2的邻居4, 5, 6进队。当前队列{ 3, 4, 5, 6}。
 (从2扩散到4、5、6。)
(d)3出队,7, 8进。当前队列{ 4, 5, 6, 7, 8}。
 (从3扩散到7、8。)

**解决**

定义图形和移动方向

    int dir[][]={  //左上角坐标是(0, 0)。顺时针。
{-,}, //向左。
{,-}, //向上
{,}, //向右
{,} //向下
};

循环解决

    for(int i=; i<; i++) {
//按左、上、右、下,4个方向顺时针逐一搜索。
next.x = start.x + dir[i][];
next.y = start.y + dir[i][];
if(CHECK(next.x,next.y) && room[next.x][next.y]=='.') {
room[next.x][next.y]='#';
//进队之后,标记为已经处理过。
num++;
q.push(next);
}
}

完整代码

   #include<bits/stdc++.h>
using namespace std;
char room[][];
int dir[][] = {
{-,}, //向左。左上角坐标是(0, 0)
{,-}, //向上
{,}, //向右
{,} //向下
};
int Wx, Hy, num; //Wx行,Hy列。用num统计可走的位置有多少
#define CHECK(x, y) (x<Wx && x>=0 && y >=0 && y<Hy) //是否在room里
struct node {int x,y;};
void BFS(int dx,int dy){
num=; //起点也包含在砖块内
queue <node> q; //队列中放坐标点
node start, next;
start.x = dx;
start.y = dy;
q.push(start);
while(!q.empty()) {
start = q.front();
q.pop();
//cout<<"out"<<start.x<<start.y<<endl; //打印出队列情况,进行验证
for(int i=; i<; i++) { //按左、上、右、下,4个方向顺时针逐一搜索
next.x = start.x + dir[i][];
next.y = start.y + dir[i][];
if(CHECK(next.x,next.y) && room[next.x][next.y]=='.') {
room[next.x][next.y]='#'; //进队之后,标记为已经处理过
num++;
q.push(next);
}
}
}
}
int main(){
int x, y, dx, dy;
while (cin >> Wx >> Hy) { //Wx行,Hy列
if (Wx== && Hy==) //结束
break;
for (y = ; y < Hy; y++) { //有Hy列
for (x = ; x < Wx; x++) { //一次读入一行
cin >> room[x][y];
if(room[x][y] == '@') { //读入起点
dx = x;
dy = y;
}
}
}
num = ;
BFS(dx, dy);
cout << num << endl;
}
return ;
}
 

bfs,队列的更多相关文章

  1. POJ 3278 Catch That Cow[BFS+队列+剪枝]

    第一篇博客,格式惨不忍睹.首先感谢一下鼓励我写博客的大佬@Titordong其次就是感谢一群大佬激励我不断前行@Chunibyo@Tiancfq因为室友tanty强烈要求出现,附上他的名字. Catc ...

  2. BFS 队列

    Plague Inc. is a famous game, which player develop virus to ruin the world. JSZKC wants to model thi ...

  3. 农夫过河 (BFS)(队列)

    1 .问题描述 要求设计实现农夫过河问题(农夫带着一只狼,一只养,一棵白菜,一次只能带一个东西)如何安全过河. 2 .问题的解决方案: 可以用栈与队列.深度优先搜索算法及广度优先搜索算法相应的原理去解 ...

  4. 拆边+BFS队列骚操作——cf1209F

    这个拆边+队列操作实在是太秒了 队列头结点存的是一个存点集的vector,1到这个点集经过的路径权值是一样的,所以向下一层拓展时,先依次走一遍每个点的0边,再走1边...以此类推,能保证最后走出来的路 ...

  5. POJ——3278 Catch That Cow(BFS队列)

    相比于POJ2251的三维BFS,这道题做法思路完全相同且过程更加简单,也不需要用结构体,check只要判断vis和左右边界的越界情况就OK. 记得清空队列,其他没什么好说的. #include< ...

  6. hdoj 2612 Find a way【bfs+队列】

    Find a way Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. poj 3278 Catch That Cow(bfs+队列)

    Description Farmer John has been informed of the location of a fugitive cow and wants to catch her i ...

  8. HDU 6171 Admiral(双向BFS+队列)题解

    思路: 最大步骤有20,直接BFS会超时. 因为知道开始情况和结果所以可以用双向BFS,每个BFS规定最大步骤为10,这样相加肯定小于20.这里要保存每个状态搜索到的最小步骤,用Hash储存.当发现现 ...

  9. 剑指offer:对称的二叉树(镜像,递归,非递归DFS栈+BFS队列)

    1. 题目描述 /** 请实现一个函数,用来判断一颗二叉树是不是对称的. 注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的 */ 2. 递归 思路: /** 1.只要pRoot.left和 ...

  10. bfs(队列模板)

    [题目描述] 当你站在一个迷宫里的时候,往往会被错综复杂的道路弄得失去方向感,如果你能得到迷宫地图,事情就会变得非常简单. 假设你已经得到了一个n*m的迷宫的图纸,请你找出从起点到出口的最短路. [输 ...

随机推荐

  1. App更新之dialog数字进度条

    App更新之dialog数字进度条 前言:现在一般的Android软件都是需要不断更新的,当你打开某个app的时候,如果有新的版本,它会提示你有新版本需要更新.当有更新时,会弹出一个提示框,点击下载, ...

  2. qt 拖放dropEvent

    1.拖放操作分为两个截然不同的动作: 拖动和放下. 拖动通过 void dragEnterEvent(QDragEnterEvent * event); 来实现. 放下通过 void dropEven ...

  3. TCP协议 状态解析和状态统计

    一.三次握手和四次挥手 1.建立连接(三次握手)   (1)服务器会处于listen状态,客户端发送一个带SYN标志的TCP报文到服务器.   (2)服务器端回应客户端的请求,这是三次握手中的第2个报 ...

  4. WebAPI应用问题整理

    这两天在实现一个WebAPI的服务过程中遇到了下面的一些问题 1, 一个Controller中添加多个Action 基于模板创建WebAPI项目后,项目中会自动生成一个ValueController的 ...

  5. js之yeild

    1.万恶的回调 对前端工程师来说,异步回调是再熟悉不过了,浏览器中的各种交互逻辑都是通过事件回调实现的,前端逻辑越来越复杂,导致回调函数越来越多,同时 nodejs 的流行也让 javascript ...

  6. Scratch3.0——克隆代码仓库的正确姿势

    原文地址:https://blog.csdn.net/weiwoyonzhe/article/details/86603450 对Scratch3.0进行二次开发,首先要在github上fock官方代 ...

  7. 简说MVC Filter

    Filter与FilterProvider之间的关系 根据用途和执行时机的不同,MVC主要分为以下5种类型的过虑器:AuthenticationFilter.AuthorizationFilter.A ...

  8. Skype for Business 安装组件RewriteModule失败

    最近QQ网友提到部署Skype for Business,安装组件时提示安装必备组件失败:RewriteModule,如下图,安装文件名是rewrite_2.0_rtw_x64.msi,尝试手动安装也 ...

  9. linux man指令问题

    linux man指令问题 2010-1-13 13:33 提问者: 钟离伊轩 man命令执行时,可加入数值,来限制帮助级别. 这句话对不对啊???? 我记得man page是分章节的..好像可以加数 ...

  10. 10、Node.js模块系统

    ##################################################################################介绍Node.js模块系统为了让No ...