Description
有这样一块土地,它可以被划分成N×M个正方形小块,每块面积是一平方英寸,第i行第j列的小块可以表示成P(i,j)。这块土地高低不平,每一小块地P(i,j)都有自己的高度H(i,j)(单位是英寸)。
一场倾盆大雨后,这块地由于地势高低不同,许多低洼地方都积存了不少降水。假如你已经知道这块土地的详细信息,你能求出它最多能积存多少立方英寸的降水么?
Input
输入文件第一行有两个数,N,M(1<=N, M <=100),表示土地的规模是N×M平方英寸。
以下有N行,每行有M个整数,表示每块地的高低(每个整数在[1,10000]内,以英寸为单位)。
Output
输出文件只有一行,一个数,表示土地中最多能积存多少立方英寸的水。
Sample Input
3 6
3 3 4 4 4 2
3 1 3 2 1 4
7 3 1 6 4 1
Sample Output
5
HINT
Source
把边界上的点插入一个以高度为关键字的大根堆然后扩展
Codevs上被卡内存了T_T
#include<iostream>
#include<cstdio>
#include<queue>
#define MAXN 102
#define GET (ch>='0'&&ch<='9')
using namespace std;
short n,m;
int ans;
short a[MAXN][MAXN],dx[5]={0,-1,0,1,0},dy[5]={0,0,1,0,-1};
bool vis[MAXN][MAXN],Vis[MAXN][MAXN];
struct node
{
short x,y,h;
bool operator <(const node& a)const
{return h>a.h;}
};
priority_queue<node> heap;
void in(short &x)
{
char ch=getchar();x=0;
while (!GET) ch=getchar();
while (GET) x=x*10+ch-'0',ch=getchar();
}
void dfs(short x,short y,short h)
{
for (short i=1;i<=4;i++)
{
short X=x+dx[i],Y=y+dy[i];
if (vis[X][Y]) continue;
if (a[X][Y]<=h) ans+=h-a[X][Y],vis[X][Y]=1,dfs(X,Y,h);
else
if (!Vis[X][Y]) Vis[X][Y]=1,heap.push((node){X,Y,a[X][Y]});
}
}
int main()
{
in(n);in(m);
for (short i=0;i<=n+1;i++)
for (short j=0;j<=m+1;j++) vis[i][j]=Vis[i][j]=1;
for (short i=1;i<=n;i++)
for (short j=1;j<=m;j++)
{
in(a[i][j]);vis[i][j]=0;Vis[i][j]=0;
if (i==1||i==n||j==1||j==m) Vis[i][j]=1,heap.push((node){i,j,a[i][j]});
}
while (!heap.empty())
{
node t=heap.top();heap.pop();
if (!vis[t.x][t.y]) vis[t.x][t.y]=1,dfs(t.x,t.y,t.h);
}
cout<<ans<<endl;
}