【poi1999】【cogs239】【积水】【堆】【灌水法】【贪心】

原创 2015年07月10日 21:31:58

问题描述

有这样一块土地,它可以被划分N*M个正方形小块,每块面积是一平方英寸,第i行第j列的小块可以表示成P(i,j)。这块土地高低不平,每一小块地P(i,j)都有自己的高度H(i,j)(单位是英寸)。

一场倾盆大雨后,由于这块地地势高低不同,许多低洼地方都积存了不少降水。假如你已经知道这块土地的详细信息,你能求出它最多能积存多少立方英寸的降水么?

输入格式

输入文件的第一行是两个正整数n和m,1<=n<=100,1<=m<=100,表示土地的尺寸。下面n行,每行m个整数(1..10000);第j行第i个数表示第j行第i列立方体的高。

输出格式

输出文件只有一个数,表示在这个建筑上可以聚合的积水的最大值

输入输出样例

输入

3 6
3 3 4 4 4 2
3 1 3 2 1 4
7 3 1 6 4 1

输出

5

下图是其方案:

Image:Wod.png

题解:按高度建一个小根堆,一开始把所有边界上的点入堆,从中取出高度最小的点,从该点开始floodfill,如果碰到比他高的点,就把那个点入堆,如果碰到比他低或相等的点,将高度差累加进答案,然后从那个点继续floodfill。重复以上过程直到堆空。

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
struct use{
	int x,y,h;
};
bool operator<(use x,use y){return x.h<y.h;}  
priority_queue<use>q;  
int map[101][101],dx[5],dy[5],n,m,ans;
bool f[101][101],ff[101][101];
inline int in(){
    char c=getchar();
    int x=0;
    while(c<'0'||c>'9')c=getchar();
    for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';
    return x;
}
inline void floodfill(int x,int y,int hh)
{
	//cout<<x<<' '<<y<<' '<<hh<<endl;
	for (int i=1;i<=4;i++)
	  {
	    int xx,yy;
	    xx=x+dx[i];yy=y+dy[i];
	    if (xx>0&&xx<=n&&yy>0&&yy<=m&&!f[xx][yy])
	      {
	        if (map[xx][yy]<=-hh) {ans+=-hh-map[xx][yy];f[xx][yy]=true;floodfill(xx,yy,hh);}
	         else 
	          {
	             if (!ff[xx][yy])
				 {
				  use a;
	              a.x=xx;a.y=yy;a.h=-map[xx][yy];q.push(a);ff[xx][yy]=true;
	             }
			  }
	      }
	  }
}
int main()
{
    freopen("wod.in","r",stdin);
    freopen("wod.out","w",stdout);
	n=in();m=in();
    dx[1]=1;dx[2]=0;dx[3]=-1;dx[4]=0;
    dy[1]=0;dy[2]=1;dy[3]=0;dy[4]=-1;
	for (int i=1;i<=n;i++)
      for (int j=1;j<=m;j++)
        {
           map[i][j]=in();
           if (i==1||i==n||j==1||j==m)
             {
                use a;
                a.x=i;a.y=j;a.h=-map[i][j];
                q.push(a);
                ff[i][j]=true;
             }
        }
    while (!q.empty())
     {
	   use a;
       a=q.top();q.pop();
       if (!f[a.x][a.y]){f[a.x][a.y]=true;floodfill(a.x,a.y,a.h);}
     }
    cout<<ans;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

【BzoJ 1601】【灌水】【最小生成树】【贪心决策】【并查集】

1601: [Usaco2008 Oct]灌水 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 2103  Solved: 1384 [Submi...
  • ODPOOP
  • ODPOOP
  • 2017年10月18日 21:33
  • 70

【GDOI2014模拟】旅行(水法)

Description给出一张n个点,m条边的图,你可以选择一些边,使得1和n,2和n-1,3和n-2…k和n-k+1联通。代价为这些边的边权和。 求最小代价。 n...

【bzoj 2936】[Poi1999]降 水(floodfill算法(BFS))

岁月氤氲着时光,驼铃摇碎了记忆

[BZOJ2929][POI1999]洞穴攀行(网络流)

无愧于天,无愧于地,无怍于人,无惧于鬼,这样,人生。

Poi1999基因片段(并查集)

问题描述 有这样一段遗传基因K,它是由一系列的自然数组成:K=a1,a2,a3,a4……am。在该段基因中,连续的两个自然数被称做它的“特征”。 例如对基因段:8, 5, 1, 4, 2, 3 (5,...

[BZOJ2927][Poi1999]多边形之战(博弈)

题目描述传送门题解有邻边的多边形连边,问题转化为一棵树,有一个节点是黑色节点,每次删除一个叶子节点,能删掉黑色节点的人获胜 把黑色节点看做根 如果黑色节点只有一个儿子,先手必胜① 只有三个点并且...

POI1999.Store-keeper(推箱子)——点双连通分量+割点+bfs

http://www.bnuoj.com/v3/problem_show.php?pid=21155题目描述:有一个n*m的地图,S表示墙,w表示空地,P表示箱子的起始位置,K表示目标位置,M表示人的...

BZOJ 2929: [Poi1999]洞穴攀行 最大流

2929: [Poi1999]洞穴攀行 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 388  Solved: 215 [Submit][Sta...

【bzoj2929】[Poi1999]洞穴攀行 最大流

题目翻译有问题。 应该是与1和n联通的边只能走一次,其他的随便走。 源点S向1直接到达的点连一条容量为1的边 直接到达n的点向汇点T连一条容量为1的边 其他边变成容量为inf的边 最大流即为答案 ...

BZOJ 2926 Poi1999 空立方体问题

题目大意:给定一个空间上的n(n≤5000)n(n\leq 5000)个点,你需要输出一个点(x,y,z)(x,y,z),满足: 1.0≤x,y,z≤1060\leq x,y,z\leq 10^6 ...
  • PoPoQQQ
  • PoPoQQQ
  • 2015年07月03日 15:35
  • 953
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【poi1999】【cogs239】【积水】【堆】【灌水法】【贪心】
举报原因:
原因补充:

(最多只允许输入30个字)