一、关于优先队列

队列(queue)这种东西广大OIer应该都不陌生,或者说,队列都不会你还学个卵啊(╯‵□′)╯︵┻━┻咳咳,通俗讲,队列是一种只允许从前端(队头)删除元素、从后端(队尾)插入元素的数据结构。而优先队列(priority queue)是一种赋予每个队列中元素以一个优先级的队列。在执行删除操作时,优先队列会删除具有最高优先级的元素。如此奇妙的优先队列有什么用呢,举个例子,给定一个长为n的序列和m组询问,对于每组询问,我们要找出删去序列中最小的数,再向序列加入一个数。朴素的想法是对每个询问从头到尾扫一遍,找出最小值,时间复杂度为O(nm)。而优先队列可以将时间复杂度降低到O(mlgn)的级别。那它是怎么做到的呢?其实,优先队列(又称堆)是一颗完全二叉树,其每个子节点与父节点间都具有某种特性(即为我们规定的优先级)。二叉树的性质决定了优先队列维护操作O(lgn)的复杂度。

二、STL之priority_queue

优先队列好用归好用,然而,它不好写_(:з」∠)_但是,STL(Standard Template Library 标准模板库)里给出了优先队列的模板~\(≧▽≦)/~

priority_queue定义在头文件<queue>里,和普通队列一样,priority_queue拥有如下操作:

1、priority_queue<Type, Container, Functional>Q:创建一个新的优先队列Q,其Type为其数据类型,Container 为保存数据的容器,Functional 为元素比较方式;

  特别说明:Container必须是用数组实现的容器,默认为vector;Functional默认为operator <。所以如果我们把Container和Functional都缺省,优先队列就是一个队头元素最大的大根堆。

2、Q.top():返回队头元素;

3、Q.pop():删除队列头部元素;

4、Q.push(x):在队尾增加元素x;

5、Q.empty():判断队列是否为空(如果队列为空则返回true,否则,返回false);

6、Q.size():返回队列中元素个数。

三、OpenJudge-4980拯救行动题解

描述

公主被恶人抓走,被关押在牢房的某个地方。牢房用N*M (N, M <= 200)的矩阵来表示。矩阵中的每项可以代表道路(@)、墙壁(#)、和守卫(x)。 
英勇的骑士(r)决定孤身一人去拯救公主(a)。我们假设拯救成功的表示是“骑士到达了公主所在的位置”。由于在通往公主所在位置的道路中可能遇到守卫,骑士一旦遇到守卫,必须杀死守卫才能继续前进。 
现假设骑士可以向上、下、左、右四个方向移动,每移动一个位置需要1个单位时间,杀死一个守卫需要花费额外的1个单位时间。同时假设骑士足够强壮,有能力杀死所有的守卫。

给定牢房矩阵,公主、骑士和守卫在矩阵中的位置,请你计算拯救行动成功需要花费最短时间。

输入

第一行为一个整数S,表示输入的数据的组数(多组输入)
随后有S组数据,每组数据按如下格式输入 
1、两个整数代表N和M, (N, M <= 200). 
2、随后N行,每行有M个字符。"@"代表道路,"a"代表公主,"r"代表骑士,"x"代表守卫, "#"代表墙壁。

输出

如果拯救行动成功,输出一个整数,表示行动的最短时间。
如果不可能成功,输出"Impossible"

原题链接→_→OpenJudge-4980拯救行动

读了题我们发现,这就是一个宽搜嘛。我们只要以时间定义优先级,把每个点能拓展的状态放入优先队列处理就可以了。

愉快的贴上代码:

 #include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
const int MAXL=;
int dir[]={-,,,},dir_[]={,,-,};
int s;
int n,m;
int map[MAXL][MAXL];
bool vis[MAXL][MAXL];
int dx,dy;
struct node
{
int x,y,time;
friend bool operator < (node A,node B){return A.time>B.time;}
//重载 < ,定义时间为优先级,时间小的元素置于队首
};
priority_queue <node> q;//priority_queue <node,vector<node>,operator <> q;
int main()
{
scanf("%d",&s);
while(s--)
{
while(!q.empty())q.pop();//清空队列q,注意:没有q.clear()的用法
memset(vis,false,sizeof(vis));
memset(map,,sizeof(map));
scanf("%d%d",&n,&m);
for(int i=;i<=n;++i)
{
char c[MAXL];
scanf("%s",c);
for(int j=;j<m;++j)
{
if(c[j]=='a')dx=i,dy=j+;
else if(c[j]=='r')q.push((node){i,j+,}),vis[i][j+]=true;
else if(c[j]=='x')map[i][j+]=;//1代表守卫
else if(c[j]=='#')map[i][j+]=;//2代表墙壁
}
}
while(!q.empty())
{
int x=q.top().x,y=q.top().y,time=q.top().time;
if(x==dx&&y==dy)break;
for(int i=;i<;++i)
{
if(x+dir[i]<||x+dir[i]>n||y+dir_[i]<||y+dir_[i]>m)continue;
if(vis[x+dir[i]][y+dir_[i]]||map[x+dir[i]][y+dir_[i]]==)continue;
vis[x+dir[i]][y+dir_[i]]=true;
if(map[x+dir[i]][y+dir_[i]]==)q.push((node){x+dir[i],y+dir_[i],time+});
else if(map[x+dir[i]][y+dir_[i]]==)q.push((node){x+dir[i],y+dir_[i],time+});
}
q.pop();
}
if(q.empty())printf("Impossible");
else printf("%d",q.top().time);
printf("\n");
}
return ;
}

OpenJudge-4980拯救行动

弱弱地说一句,本蒟蒻码字也不容易,转载请注明出处http://www.cnblogs.com/Maki-Nishikino/p/6056072.html

【STL】优先队列priority_queue详解+OpenJudge-4980拯救行动的更多相关文章

  1. C++ STL 优先队列 priority_queue 详解(转)

    转自https://blog.csdn.net/c20182030/article/details/70757660,感谢大佬. 优先队列 引入 优先队列是一种特殊的队列,在学习堆排序的时候就有所了解 ...

  2. 优先队列priority_queue详解

    转载链接

  3. STL bind1st bind2nd详解

    STL bind1st bind2nd详解   先不要被吓到,其实这两个配接器很简单.首先,他们都在头文件<functional>中定义.其次,bind就是绑定的意思,而1st就代表fir ...

  4. C++ STL bitset 容器详解

    C++ STL bitset 容器详解 本篇随笔讲解\(C++STL\)中\(bitset\)容器的用法及常见使用技巧. \(bitset\)容器概论 \(bitset\)容器其实就是个\(01\)串 ...

  5. 2.3 C++STL vector容器详解

    文章目录 2.3.1 引入 2.3.2 代码实例 2.3.3 运行结果 总结 2.3.1 引入 vector 容器 动态数组 可变数组 vector容器 单口容器(尾部操作效率高) vector动态增 ...

  6. multimap 和priority_queue详解

    上一期是关于STL和并查集结合的例题,也附了STL中部分容器的使用摘要,由于是从网上东拼西凑的,感觉有的关键点还是没解释清楚,现在从其中摘出两个容器,用例题对它们的用法进行进一步解释. 以下是例题的介 ...

  7. [GeekBand] STL 仿函数入门详解

    本文参考文献::GeekBand课堂内容,授课老师:张文杰 :C++ Primer 11 中文版(第五版) page 37 :网络资料: 叶卡同学的部落格  http://www.leavesite. ...

  8. C++ STL 优先队列 (priority_queue)

    std::priority_queue <queue> 优先队列   优先队列是一种容器适配器,根据某些严格的弱排序标准,使其第一个元素始终包含的最大元素.   这种特性类似于堆,它可以在 ...

  9. C++ STL之vector详解

    转自http://blog.sina.com.cn/s/blog_9f1c0931010180cy.html Vectors   vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作 ...

随机推荐

  1. 【转】24Cxx 系列EEPROM通用程序及应用

    关于I2C 学习的时候介绍得最多的就是24C02 这里存储EEPROM了,但学的时候基本只是讲讲简单的I2C 的总线数据传输而已,即使先gooogle上搜索也绝大部分这这样的文章,很少有说到如何在实际 ...

  2. React Native IOS源码初探

    原文链接 http://www.open-open.com/lib/view/open1465637638193.html 每个项目都有一个入口,然后进行初始化操作,React Native 也不例外 ...

  3. ssh 配合 tar 实现远程推送

    tar命令和ssh配合使用 如何在空间不是很富裕的情况,把文件从一个分区tar到另外一个分区,其实还有很多办法的,使用管道命令就可以实现 如: #tar -cvf home |(cd /datavg3 ...

  4. 导入csv文件到mysql

    原文 给自己做备份的,高手们请忽略. 数据太大,用数据库客户端软件直接导入非常卡,还是直接执行SQL吧. 1.指定文件路径. 2.字段之间以逗号分隔,数据行之间以\r\n分隔(我这里文件是以\n分隔的 ...

  5. Response.End抛出ThreadAbortException 异常

    最近在写程序过程中遇到了一个匪夷所思的错误:Response.End()方法抛出了ThreadAbortException异常,我的代码如下: public void doResponse(){ st ...

  6. 详解JS跨域问题

    什么是跨域? 概念:只要协议.域名.端口有任何一个不同,都被当作是不同的域.             JavaScript   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...

  7. github Android-Universal-Image-Loader

    目存在于Github上面https://github.com/nostra13/Android-Universal-Image-Loader,我们可以先看看这个开源库存在哪些特征 多线程下载图片,图片 ...

  8. ffmpeg将图片合成视频

    本来想做个android录制屏幕的功能,但是目前只能是截图 然后把图片合成视频,这里就需要用到 ffmpeg 在做之前也是参考了其它一些比较不错的文章 比如:http://www.open-open. ...

  9. 夺命雷公狗-----React---23--小案例之react经典案例todos(完成添加任务)

    我们这次来处理用户添加的数据,我们还是赵老规矩看看组建大致图... 子组件对父组建进行数据的传递其实是react内部的机智进行处理的了,, 代码如下所示: <!DOCTYPE html> ...

  10. WEB前端开发CSS基础样式全面总结

    Web前端开发css基础样式全面总结 颜色和单位的使用 颜色 用颜色的名字表示颜色,比如:red 用16进制表示演示 比如:#FF0000 用rgb数值表示颜色,rgb(红,绿,蓝),每个值都在0-2 ...