poj 2227 The Wedding Juicer--floodfill--bfs

来源:互联网 发布:你是唯一 知乎 编辑:程序博客网 时间:2024/06/06 16:27
/*给你一个碗,这个碗有点特殊,形状是一个矩形,每个位置上数字是这儿碗底的高度(即:四周的高度比他高的时候这里就可以盛水),求这个碗最多可以装多少水思路是:这个碗可以被分解成几个(也可能是一个),每个的形状都和我们见到的普通碗一样(即四周高,中间低),找到这个碗的边缘最低的那块,这个碗盛的水的最高水位就是这个高度,故从这个点开始扩展,比其低的是可以盛水的(加上高度差,并加入q队列,以便继续扩展下去),比其高的是边缘(还可能是其他碗的边缘,故加入pre优先队列用于寻找下一个碗,所有的碗都是通过寻找最低边缘找到的)*/#include<stdio.h>#include<string.h>#include<queue>using namespace std;struct node{int x,y;__int64 h;friend bool operator <(node a,node b){return a.h>b.h;}};int dir[][2]={-1,0,0,1,1,0,0,-1};priority_queue<node>pre;queue<node>q;__int64 map[310][310];int vis[310][310];int w,h;__int64 ans;void ini(){int i;node t;for(i=1;i<=w;i++){t.x=1;t.y=i;t.h=map[t.x][t.y];pre.push(t);vis[t.x][t.y]=1;t.x=h;t.y=i;t.h=map[t.x][t.y];pre.push(t);vis[t.x][t.y]=1;}for(i=2;i<h;i++){t.x=i;t.y=1;t.h=map[t.x][t.y];pre.push(t);vis[t.x][t.y]=1;t.x=i;t.y=w;t.h=map[t.x][t.y];pre.push(t);vis[t.x][t.y]=1;}}void bfs(){node t,n;int k;while(!pre.empty()){t=pre.top();pre.pop();__int64 max=t.h;q.push(t);while(!q.empty()){node cur;cur=q.front();q.pop();for(k=0;k<4;k++){n.x=cur.x+dir[k][0];n.y=cur.y+dir[k][1];n.h=map[n.x][n.y];if(n.x>0&&n.x<=h&&n.y>0&&n.y<=w&&!vis[n.x][n.y]){vis[n.x][n.y]=1;if(n.h>max)//这里错过,之前写成了n.h>cur.h,寻找的是比当前这个池子最大水平线高的岸,若n.h>cur.h会导致不是岸的地方变成岸(本来可以在这儿注水,现在不可以了){pre.push(n);}else{q.push(n);ans+=max-n.h;}}}}//printf("%I64d\n",ans);}}int main(){node t,n;scanf("%d%d",&w,&h);memset(vis,0,sizeof(vis));int i,j,k;ans=0;for(i=1;i<=h;i++)for(j=1;j<=w;j++)scanf("%I64d",&map[i][j]);ini();bfs();printf("%I64d\n",ans);return 0;}

原创粉丝点击