您的位置:首页 > 其它

nyoj 547 优先队列

2014-04-29 17:27 120 查看
#include<stdio.h>

#include<string.h>

#include<queue>//水杯盛水问题,用优先队列不断从最小的边缘开始

using namespace std;

int n,m;

#define N 400

int p

;

struct node {

int x,y,w;

friend bool operator<(node a,node b) {//优先队列

return a.w>b.w;//从小到大出队

}

};

int visit

;

int dis[4][2]={1,0,0,1,-1,0,0,-1};//四个方向

int judge(int x,int y) {

if(x<=n&&x>=1&&y<=m&&y>=1&&!visit[x][y])

return 1;

return 0;

}

int main() {

int i,j,sum;

while(scanf("%d%d",&m,&n)!=EOF) {

priority_queue<node>q;

node cur,next;

memset(visit,0,sizeof(visit));

for(i=1;i<=n;i++)

for(j=1;j<=m;j++) {

scanf("%d",&p[i][j]);

if(j==1||j==m||i==1||i==n) {//先将杯子的边缘加入

cur.x=i;cur.y=j;

cur.w=p[i][j];

visit[i][j]=1;//标记边缘不能搜索

q.push(cur);

}

}

sum=0;

while(!q.empty()) {//每次从最小的边缘开始

cur=q.top();

q.pop();

for(i=0;i<4;i++) {

int xx=next.x=cur.x+dis[i][0];

int yy=next.y=cur.y+dis[i][1];

if(judge(xx,yy)) {//判断

visit[xx][yy]=1;

if(p[xx][yy]<cur.w) {//如果当前的边缘大于水杯内部

sum+=cur.w-p[xx][yy];//高度差即为所能盛的水

next.w=cur.w;//改变当前点值

q.push(next);

}

else {//

next.w=p[xx][yy];/

q.push(next);//

}

}

}

}

printf("%d\n",sum);//

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: