POJ 2227 The Wedding Juicer (优先级队列+bfs+dfs)
思路描述来自:http://hi.baidu.com/perfectcai_/item/701f2efa460cedcb0dd1c820
也可以参考黑书P89的积水。
题意:Farmer John有一个碗,形状如下,给你一个w*h平面,每个1*1的位置有一个高度Hij,问用这个碗来装牛奶,最多可以装多少体积。
例如:
555
515
555
这个可以装4体积,只有中间的1位置可以装;
再如:
555
512
555
这个可以装1体积,只有中间的1位置可以装,而装到2时就会开始漏出,因为液体是可以流动的;
分析:
由例子二可以很深刻的理解如果在一个桶边上打一些洞,那么之后这个桶能装的水取决于最低的那个洞的高度,
接着这个思路往下,对于最开始,只要找到这w*h外围的方格放入队列,这是最开始的边缘,取出其中最低的点x,
然后考察它周围4个位置中合法并且可以积水的点中的格子y,高度为Hy。
若y的高度大于x的高度,那么直接把Hy放入队列,并标记为禁止积水;
如果小于,把Hx放入队列,且ans+=Hx-Hy,意味着y位置可以放Hx-Hy体积的水,也标记为禁止积水。
然后再取禁止积水的格子中最低的,即队列中的最小值,继续向四周拓展。
核心思想:找最低边缘,把积过水的格子看成高度更新后的边缘。
由于要取最小高度,所以用到优先级队列,至于如何向四周扩展,我用的是bfs+dfs
#include <iostream>
#include <queue>
#include <stdio.h>
#include <algorithm> using namespace std;
const int maxn=;
int w,h;
long long block[maxn][maxn];
int mark[maxn][maxn]; //标记是否可以积水
long long ans=;
struct Node{
int x,y;
long long height;
bool operator<(const Node tmp)const{
return height>tmp.height;
}
}tmp;
priority_queue<Node> q;
//终于知道为什么AC不了了啊,原来之前的参数height写得是h,与整个board的高度h重复了额
void dfs(int x,int y,long long height){
if(x<||x>h||y<||y>w)
return;
mark[x][y]=;
ans+=height-block[x][y];
//上
if(x->&&mark[x-][y]){
if(height>block[x-][y])
dfs(x-,y,height);
else{
mark[x-][y]=;
tmp.x=x-;
tmp.y=y;
tmp.height=block[x-][y];
q.push(tmp);
}
}
//下
if(x+<=h&&mark[x+][y]){
if(height>block[x+][y])
dfs(x+,y,height);
else{
mark[x+][y]=;
tmp.x=x+;
tmp.y=y;
tmp.height=block[x+][y];
q.push(tmp);
}
}
//左
if(y->&&mark[x][y-]){
if(height>block[x][y-])
dfs(x,y-,height);
else{
mark[x][y-]=;
tmp.x=x;
tmp.y=y-;
tmp.height=block[x][y-];
q.push(tmp);
}
}
//右
if(y+<=w&&mark[x][y+]){
if(height>block[x][y+])
dfs(x,y+,height);
else{
mark[x][y+]=;
tmp.x=x;
tmp.y=y+;
tmp.height=block[x][y+];
q.push(tmp);
}
}
}
int main()
{
Node node;
scanf("%d%d",&w,&h);
for(int i=;i<=h;i++){
for(int j=;j<=w;j++){
mark[i][j]=;
scanf("%I64d",&block[i][j]); //存储高度
if(i==||i==h||j==||j==w){
mark[i][j]=; //表示禁止积水
node.x=i;
node.y=j;
node.height=block[i][j];
q.push(node);
}
}
}
ans=;
//bfs+dfs
while(!q.empty()){
node=q.top();
q.pop();
dfs(node.x,node.y,node.height);
}
cout<<ans<<endl;
return ;
}
下面给出只用队列+bfs的代码,速度稍慢一点:
参考链接:http://www.cnblogs.com/dongsheng/archive/2013/04/25/3043512.html
#include <iostream>
#include <queue>
#include <stdio.h>
#include <algorithm> using namespace std;
const int maxn=;
int w,h;
long long block[maxn][maxn];
int mark[maxn][maxn];
int dir[][] = {-,,,,,,,-};
long long ans=;
struct Node {
int x,y;
long long h;
bool operator<(const Node tmp)const {
return h>tmp.h;
}
} tmp;
priority_queue<Node> q;
long long BFS()
{
long long ans = ;
int i, j;
Node t1, t2;
while(!q.empty())
{
t1 = q.top();
q.pop();
for(int k = ; k < ; ++k)
{
i = t1.x + dir[k][];
j = t1.y + dir[k][];
if(i > && i <= h && j > && j <= w && mark[i][j])
{
if(block[i][j] < t1.h)
{
ans += t1.h - block[i][j];
t2.x = i;
t2.y = j;
t2.h = t1.h;
}
else
{
t2.x = i;
t2.y = j;
t2.h = block[i][j];
}
mark[i][j] = ;
q.push(t2);
}
}
}
return ans;
}
int main() {
Node node; //cin>>w>>h;
while(scanf("%d%d",&w,&h)!=EOF) {
for(int i=; i<=h; i++) {
for(int j=; j<=w; j++) {
mark[i][j]=;
scanf("%I64d",&block[i][j]);
if(i==||i==h||j==||j==w) {
mark[i][j]=; //表示禁止积水
node.x=i;
node.y=j;
node.h=block[i][j];
q.push(node);
}
}
}
ans=;
printf("%I64d\n",BFS());
}
return ;
}
POJ 2227 The Wedding Juicer (优先级队列+bfs+dfs)的更多相关文章
- POJ 3253 Fence Repair 贪心 优先级队列
Fence Repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 77001 Accepted: 25185 De ...
- 【POJ 3614 Sunscreen】贪心 优先级队列
题目链接:http://poj.org/problem?id=3614 题意:C头牛去晒太阳,每头牛有自己所限定的spf安全范围[min, max]:有L瓶防晒液,每瓶有自己的spf值和容量(能供几头 ...
- POJ:3083 Children of the Candy Corn(bfs+dfs)
http://poj.org/problem?id=3083 Description The cornfield maze is a popular Halloween treat. Visitors ...
- 【BFS+优先级队列】Rescue
https://www.bnuoj.com/v3/contest_show.php?cid=9154#problem/I [题意] 给定一个n*m的迷宫,A的多个小伙伴R要去营救A,问需要时间最少的小 ...
- POJ 2431 Expedition 贪心 优先级队列
Expedition Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 30702 Accepted: 8457 Descr ...
- ACM/ICPC 之 优先级队列+设置IO缓存区(TSH OJ-Schedule(任务调度))
一个裸的优先级队列(最大堆)题,但也有其他普通队列的做法.这道题我做了两天,结果发现是输入输出太过频繁,一直只能A掉55%的数据,其他都是TLE,如果将输入输出的数据放入缓存区,然后满区输出,可以将I ...
- 算法与数据结构基础 - 堆(Heap)和优先级队列(Priority queue)
堆基础 堆(Heap)是具有这样性质的数据结构:1/完全二叉树 2/所有节点的值大于等于(或小于等于)子节点的值: 图片来源:这里 堆可以用数组存储,插入.删除会触发节点shift_down.shif ...
- 体验Rabbitmq强大的【优先级队列】之轻松面对现实业务场景
说到队列的话,大家一定不会陌生,但是扯到优先级队列的话,还是有一部分同学是不清楚的,可能是不知道怎么去实现吧,其实呢,,,这东西已 经烂大街了...很简单,用“堆”去实现的,在我们系统中有一个订单催付 ...
- Java中的队列Queue,优先级队列PriorityQueue
队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...
随机推荐
- angularjs2 学习笔记(六) Form
Angular 2 Form表单 在angular2 form表单中我们需要了解表单数据绑定.数据验证.数据提交等内容,在下面的示例中并没有实际提交到后台,这部分内容在今后webapi中加以练习. 表 ...
- WPF Event 在 Command 中的应用初级篇,支持所有Event 展示松耦合设计的全部代码 - 解决TextBoxBase.TextChanged或者TextBox.TextChanged等类似事件绑定问题。
做过WPF开发的人,都知道做MVVM架构,最麻烦的是Event的绑定,因为Event是不能被绑定的,同时现有的条件下,命令是无法替代Event.而在开发过程中无法避免Event事件,这样MVVM的架构 ...
- 帮朋友 解决一道 LeetCode QJ上问题
引言 对于刷题,自己是没能力的. 最经一个朋友同事考我一道数组题 . 也许能当面试分享吧. 娱乐娱乐. 事情的开始是这样的. 前言 题目 截图 大概意思 是 在一个 数组中,找出其中两个不重复出现的元 ...
- Linux下安装宋体以及微软雅黑字体
最近工作用itext生成pdf在windows环境下没有出现中文乱码而在linux下出现中文乱码,打开pdf查看pdf编码,以及显示的编码,发现编码并没有对应.原因是使用的宋体和微软雅黑在linux环 ...
- Mysql找不到mysql.sock怎么办?
1. #ps -aux|grep mysql 找mysql的进程. #kill mysql进程号 确定全部kill光 2.直接跳第3步,无效再使用第2步 /usr/local/mysql/bin/my ...
- DSP28335矩阵键盘的检测
#include "DSP2833x_Device.h"#include "DSP2833x_Examples.h"char temp;void gpio_in ...
- PB中掉用Run以后,等Run的程序关闭以后才会执行后边的语句
OleObject wsh integer li_rc CONSTANT integer MAXIMIZED = CONSTANT integer MINIMIZED = CONSTANT integ ...
- java中的匿名内部类总结(转)
源出处: java中的匿名内部类总结 匿名内部类也就是没有名字的内部类 正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写 但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接 ...
- IT安全的本质
(1)信任:服务端信任客户端的请求参数. (2)可控:客户端的请求参数可以被控制,任意修改. 服务端信任+客户端可控 =不安全. 服务端信任+客户端不可控=安全. 服务端不信任+客户端可控=安全. 服 ...
- (转)-编写第一个ROS(创建工作空间workspace和功能包package)
原文网址:http://www.cnblogs.com/liuamin/p/5704281.html 刚接触ROS,学着写了第一个程序,怕以后忘记,就将其步骤记录下来.. 首先你必须保证你电脑已安装配 ...