队列与BFS
一.队列
1.定义
一种受限制的线性表
我们可以从队列末尾插入一个元素,可以从队列开头删掉一个元素,
也可以查询队列开头是什么
就像在食堂买饭不能插队一样,队列中的元素先进先出
2.特点与理解
队列的特点是先进先出
普通的队列用处用在一些特殊的题目
而 ### 优先队列 ###的用处却很大
他的优点是每次进队,都可以按照规定的方式排列
3.五种写法
//自己打的,可能有点烂
1>手写队列
int que[1010];
int head=0,tail=0;
2>STL队列
queue <int> sta;
sta.pop();
sta.push(...);
sta.empty()????
....
3>小/大根堆优先队列
priority queue <int,vecter<int>,greater/less<int> > sta;
4>普通优先队列
priority queue <int> sta;
sta.push(1);
sta.push(2);
输出:2,1
5>结构体优先队列
struct node
{
int a;
char b;
string c;
...
}
priority <node> sta;
4.例题
1)合并果子
这里思路已经很明显了,每次的贪心方案是开始取最小的
这里就可以用优先队列,每次入队就排序
取出最小的两个值加到sum里,输出sum即可
5.模板
与BFS结合见下
6.尺取法
见以往博客
最短子序列&&队列&&尺取法
#include<bits/stdc++.h>
using namespace std;
bool flag=true;
int ans=1e7;
int a[1000000];
int main()
{
int n,m;
cin>>n>>m;
int l=0,r=0;
int sum=0;
for(int i=0;i<n;i++) cin>>a[i];
while(flag)
{
while(r<n&&sum<=m)
sum+=a[r++];
if(sum<m) break;
ans=min(ans,r-l);
sum-=a[l++];
}
cout<<ans;
return 0;
}
二.BFS(广搜)
1.定义
2.模板
3.例题
1>洪水升级版
先用结构体定义坐标和时间(步数),先将起点入队,之后每次入队相邻的节点
当到达末尾时,输出步数
2>迷宫
方法和上题差不多,先将起点入队,然后每次进入可扩展的点,如果没有,直接出队,重复该过程,开个标记数组,将走过的标记,免进入死循环
3>填涂颜色
将整个二维数组外围上零,开一个映射数组,将映射数组里的外围连续的零全部改为1,这样只有在映射数组里和原数组里都是’0’的0改为2输出即可
总结
队列和BFS两者是相通的
是对线性算法更为灵活的运用
队列中的优先队列可以自动排序
同样的还有双向队列,循环队列等优化
在BFS实现的图论中,我们可以通过方向数组优化
在结构体开队列bfs时,记得入队和出队的顺序
结合题意选择最合适的算法与数据结构才是最优质的代码~