夏日旅行(广度优先搜索)
先补充一下队列的相关知识:
1. 队列的基本概念
队列(Queue)是一种先进先出(FIFO, First In First Out)的线性数据结构,具有以下特点:
- 只允许在队尾(rear)进行插入操作(入队)
- 只允许在队头(front)进行删除操作(出队)
- 操作顺序严格遵循"先进先出"原则
2. C++中的队列实现
2.1 STL中的queue容器
C++标准模板库(STL)提供了queue
容器适配器:
#include <queue> // 必须包含的头文件
using namespace std;queue<int> q; // 声明一个整型队列
2.2 队列的基本操作
操作 | 方法 | 说明 | 时间复杂度 |
---|---|---|---|
入队 | push() | 在队尾插入元素 | O(1) |
出队 | pop() | 删除队头元素 | O(1) |
访问队头元素 | front() | 返回队头元素(不删除) | O(1) |
访问队尾元素 | back() | 返回队尾元素(不删除) | O(1) |
判断队列是否为空 | empty() | 返回bool值表示队列是否为空 | O(1) |
获取队列大小 | size() | 返回队列中元素的个数 | O(1) |
2.3 示例代码
#include <iostream>
#include <queue>
using namespace std;int main() {queue<int> q;// 入队操作q.push(10);q.push(20);q.push(30);// 查看队列状态cout << "队列大小: " << q.size() << endl;cout << "队头元素: " << q.front() << endl;cout << "队尾元素: " << q.back() << endl;// 出队操作q.pop();cout << "出队后队头元素: " << q.front() << endl;// 遍历队列cout << "队列元素: ";while (!q.empty()) {cout << q.front() << " ";q.pop();}cout << endl;return 0;
}
3. 队列的应用场景
- 广度优先搜索(BFS):图的遍历算法
- 任务调度:CPU任务调度、打印机任务队列
- 消息传递系统:消息的缓冲和顺序处理
- 模拟现实排队系统:银行、超市等排队场景
- 数据流处理:数据包的顺序处理
4. 特殊队列类型
4.1 双端队列(deque)
#include <deque>
deque<int> dq; // 可以在两端进行插入删除操作
4.2 优先队列(priority_queue)
#include <queue>
priority_queue<int> pq; // 元素按优先级出队,默认大顶堆
4.3 循环队列
// 通常需要手动实现
class CircularQueue {int* arr;int front, rear, size;
public:// 实现循环队列的基本操作
};
题目:
代码(我自己写出来的,真是个奇迹,真是个小天才):
# include<iostream>
# include<vector>
# include<queue>
using namespace std;int N,M;
vector<vector<int>> arr(51,vector<int>(51));
vector<vector<int>> flag(51,vector<int>(51));
int start_x,start_y,end_x,end_y;struct Point{int x;int y;int step;
};
int bfs(int start_x,int start_y,int end_x,int end_y);
queue<Point> q;int main()
{cin>>N>>M;for(int i=1;i<=N;i++){for(int j=1;j<=M;j++){cin>>arr[i][j];}}cin>>start_x>>start_y>>end_x>>end_y; for(int i=1;i<=N;i++){for(int j=1;j<=M;j++){flag[i][j] = 0;}}int res = bfs(start_x,start_y,end_x,end_y);cout<<res<<endl;return 0;}int d_x[] = {0,1,0,-1};
int d_y[] = {1,0,-1,0};int bfs(int start_x,int start_y,int end_x,int end_y)
{q.push({start_x,start_y,0});flag[start_x][start_y] = 1;while(!q.empty()){int x = q.front().x;int y = q.front().y;int step = q.front().step;if(x==end_x&&y==end_y){return q.front().step;}for(int i=0;i<4;i++){int x_now = x+d_x[i];int y_now = y+d_y[i]; if(x_now>0&&x_now<=M&&y_now>0&&y_now<=N){if(flag[x_now][y_now]==0&&arr[x_now][y_now]==0){q.push({x_now,y_now,step+1});flag[x_now][y_now] = 1;}}}q.pop();}return -1;
}