题目大意:矩形,每一个格子有一个高度,求最多积水体积
题解:根据木桶效应,一个点积水取决于它周围高度最低的那个
从边界开始floodfill,易知边界上点不会积水
具体实现时用一个小根堆进行bfs,这样每个点第一个被访问一定是与其联通的格子中高度最低的,就可以求出其积水高度了
我的收获:Orz方法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define rep(i,x,y) for(int i=x;i<=y;i++)
const int M=105;
const int dx[]={0,1,-1,0,0};
const int dy[]={0,0,0,1,-1};
int n,m,ans;
int map[M][M];
int h[M][M];
bool vis[M][M];
struct data{int x,y,high;};
bool operator <(data a,data b){return a.high>b.high;}
priority_queue<data> q;
bool out(int x,int y){return x>n||x<1||y>m||y<1;}
void work()
{
while(!q.empty())
{
data u=q.top();q.pop();
rep(k,1,4)
{
int nx=u.x+dx[k],ny=u.y+dy[k];
if(out(nx,ny)||vis[nx][ny]) continue;
h[nx][ny]=max(h[nx][ny],u.high);
vis[nx][ny]=1;q.push((data){nx,ny,h[nx][ny]});
}
}
rep(i,1,n) rep(j,1,m) ans+=h[i][j]-map[i][j];
cout<<ans<<endl;
}
void init()
{
cin>>n>>m;
rep(i,1,n) rep(j,1,m) cin>>map[i][j],h[i][j]=map[i][j];
rep(i,1,n) rep(j,1,m) if(i==1||i==n||j==1||j==m) vis[i][j]=1,q.push((data){i,j,map[i][j]});
}
int main()
{
init();
work();
return 0;
}