BZOJ-1736: [Usaco2005 jan]The Wedding Juicer 婚宴的榨汁机

[文章目录]

Description

约翰的奶牛们找到了一份不错的兼职一设计冲压式榨汁机.榨汁机设计如下:
一个W* H的底座(3≤W,H≤300) 每一个1 *1的方格上都放有一个高度为B(1≤B≤109)的柱予,用来榨汁.假设柱子之间都被完美地粘合了,这样水不会顺着柱子与柱子之间的空隙流走.但是约翰一直不知道,这么一个榨汁机,到底能装多少果汁?假设榨汁机周围没有任何东西,也就是说,边界上的水都会流走,有些榨汁机则根本不能装下任何的果汁.

搜索出当前不能有水的位置。将高度从小到大排序,枚举位置,如果当前高度为一个边界(周围存在可以有水的位置),该高度即为水的高度,进行搜索灌水,灌到的位置相当于新的不能有水的位置。时间复杂度O(n*m*log(n*m))

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int lim; ll ans;
int m,n,h[310][310];
bool bor[310][310],vis[310][310];
void dfs_bor(int x,int y)
{
    if(bor[x][y]) return ;
    bor[x][y]=1;
    if(x!=1&&h[x-1][y]>=h[x][y]) dfs_bor(x-1,y);
    if(y!=1&&h[x][y-1]>=h[x][y]) dfs_bor(x,y-1);
    if(x!=n&&h[x+1][y]>=h[x][y]) dfs_bor(x+1,y);
    if(y!=m&&h[x][y+1]>=h[x][y]) dfs_bor(x,y+1);
}
int tot;
struct node
{
    int x,y,w;
}a[310*310];
bool cmp(node x,node y){return x.w<y.w;}
void dfs(int x,int y)
{
    bor[x][y]=1;
    if(h[x][y]<=lim)
    {
        ans+=lim-h[x][y];
        if(x!=1&&!bor[x-1][y]) dfs(x-1,y);
        if(x!=n&&!bor[x+1][y]) dfs(x+1,y);
        if(y!=1&&!bor[x][y-1]) dfs(x,y-1);
        if(y!=m&&!bor[x][y+1]) dfs(x,y+1);
    }
}
void work(int x,int y)
{
    if(!bor[x][y]) return ; lim=h[x][y];
    if(x!=1&&!bor[x-1][y]) dfs(x-1,y);
    if(x!=n&&!bor[x+1][y]) dfs(x+1,y);
    if(y!=1&&!bor[x][y-1]) dfs(x,y-1);
    if(y!=m&&!bor[x][y+1]) dfs(x,y+1);
}
int main()
{
    scanf("%d%d",&m,&n);
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j)
        {
            scanf("%d",&h[i][j]);
            a[++tot].x=i; a[tot].y=j; a[tot].w=h[i][j];
        }
    sort(a+1,a+tot+1,cmp);
    for(int i=1;i<=m;++i)
    {
        if(!bor[1][i]) dfs_bor(1,i);
        if(!bor[n][i]) dfs_bor(n,i);
    }
    for(int i=1;i<=n;++i)
    {
        if(!bor[i][1]) dfs_bor(i,1);
        if(!bor[i][m]) dfs_bor(i,m);
    }
    for(int i=1;i<=tot;++i)
        work(a[i].x,a[i].y);
    printf("%lld",ans);
    return 0;
}

发表评论

邮箱地址不会被公开。 必填项已用*标注