water

来源:互联网 发布:大美工 编辑:程序博客网 时间:2024/05/21 06:22

问题 B: water
时间限制: 1 Sec 内存限制: 256 MB
题目描述
有一块矩形土地被划分成 n*m 个正方形小块。这些小块高低不平,每一小块都有自己的高度。水流可以由任意一块地流向周围四个方向的四块地中,但是不能直接流入对角相连的小块中。
一场大雨后,由于地势高低不同,许多地方都积存了不少降水。给定每个小块的高度,求每个小块的积水高度。
注意:假设矩形地外围无限大且高度为0。
输入
第一行包含两个非负整数n,m。
接下来n 行每行m 个整数表示第i 行第j 列的小块的高度。
输出
输出n 行,每行m 个由空格隔开的非负整数,表示每个小块的积水高度。
样例输入
3 3
4 4 0
2 1 3
3 3 -1
样例输出
0 0 0
0 1 0
0 0 1
提示
对于20%的数据 n,m<=4

对于40%的数据 n,m<=15

对于60%的数据 n,m<=50

对于100%的数据 n,m<=300,|小块高度|<=10^9。

在每一部分数据中,均有一半数据保证小块高度非负

其实我们要求的是某个点到边界的路径中最大高度的最小值。因为一条路径能盛水的最大高度就是这条路径的上的最大高度,最终某个点能盛水的高度是所有路径上最高高度的最小值。所以可以跑spfa,求出这个,就能算出盛水的高度了。

#pragma GCC optimize("O3")#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#include<queue>#define N 300005#define inf 1000000000#define ll long longusing namespace std;int read(){    int sum=0,f=1;char x=getchar();    while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}    while(x>='0'&&x<='9'){sum=(sum<<1)+(sum<<3)+x-'0';x=getchar();}    return sum*f;}struct node{    int x,y;    node(){}    node(int x_,int y_){x=x_,y=y_;}};int n,m;int vis[304][304];ll a[304][304],dis[305][305];int wz[4][2]={0,1,0,-1,1,0,-1,0};queue<node> q;void spfa(){    while(!q.empty())    {        node x=q.front();q.pop();vis[x.x][x.y]=0;        for(int i=0;i<4;i++)        {            node to;to.x=x.x+wz[i][0],to.y=x.y+wz[i][1];            if(to.x<=1||to.x>=n||to.y>=m||to.y<=1)continue;            int k=max(a[to.x][to.y],dis[x.x][x.y]);            if(dis[to.x][to.y]>k)            {                dis[to.x][to.y]=k;                if(!vis[to.x][to.y]){vis[to.x][to.y]=1;q.push(to);}            }        }    }}int main(){    memset(dis,120,sizeof(dis));    n=read();m=read();    for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)a[i][j]=read();    for(int i=1;i<=n;i++)    {        dis[i][1]=max(0ll,a[i][1]);        dis[i][m]=max(0ll,a[i][m]);        q.push(node(i,1));q.push(node(i,m));        vis[i][1]=vis[i][m]=1;    }    for(int i=1;i<=m;i++)    {        dis[1][i]=max(0ll,a[1][i]);        dis[n][i]=max(0ll,a[n][i]);        q.push(node(1,i));q.push(node(n,i));        vis[1][i]=vis[n][i]=1;    }    spfa();    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        {            int k=max(0ll,dis[i][j]-a[i][j]);            printf("%d ",k);        }        printf("\n");    }}
原创粉丝点击