Gym - 101572E Emptying the Baltic 优先队列

Description

就 是 说 给 出 一 个 n ∗ m 的 地 形 块 , 0 表 示 海 平 面 , 负 数 表 示 地 面 在 海 水 下 , 正 数 表 示 是 陆 地 , 且 高 出 海 平 面 。 就是说给出一个n*m的地形块,0表示海平面,负数表示地面在海水下,正数表示是陆地,且高出海平面。 nm0
现 在 在 ( x , y ) 处 放 上 一 个 排 水 的 设 备 , 问 其 能 排 出 多 少 的 水 , 对 于 一 个 位 置 , 水 能 够 从 八 个 方 向 进 来 。 现在在(x,y)处放上一个排水的设备,问其能排出多少的水,对于一个位置,水能够从八个方向进来。 (x,y)


Input

1 ≤ h , w ≤ 500 1\leq h,w\leq 500 1h,w500
0 ≤ i &lt; h 0\leq i &lt; h 0i<h
0 ≤ j &lt; m 0\leq j&lt; m 0j<m


Output

总的的排水量


Solution

水往低处流。
于是需要优先最低的,即水位最深的。
考 虑 j → i 的 水 流 量 = m i n ( d e p i , d e p j ) d e p 是 离 海 平 面 的 距 离 。 考虑j \to i 的水流量 = min(dep_i,dep_j) dep是离海平面的距离。 ji=min(depi,depj)dep


Codes

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 550;
struct Node{
    int x,y;
    ll val;
    Node(){}
    Node(int _x,int _y,ll _val) {x = _x;y = _y;val = _val;}
    bool operator < (const Node &a)const {
        return val < a.val;
    }
};

priority_queue<Node> qu;
int n,m,maze[maxn][maxn];
bool vis[maxn][maxn];
int main()
{
    while(~scanf("%d%d",&n,&m)) {
        while(!qu.empty()) qu.pop();
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++) {
            for(int j=0;j<m;j++) {
                scanf("%d",&maze[i][j]); 
                if(maze[i][j] >= 0) {
                    maze[i][j] = 0;
                }
                else {
                    maze[i][j] = -maze[i][j];
                }
            }
        }
        int x,y;
        scanf("%d%d",&x,&y);x--;y--;
        qu.push(Node(x,y,maze[x][y]));
        vis[x][y] = true;
        ll res = 0;
        while(!qu.empty()) {
            Node now = qu.top();qu.pop();
            res += now.val;
            for(int i=-1;i<=1;i++) for(int j=-1;j<=1;j++) {
                int mx = now.x + i,my = now.y + j;
                if(mx<0 || mx >= n || my<0 || my >= m || vis[mx][my] || maze[mx][my]==0) continue;
                vis[mx][my] = 1;
                // maze[mx][my] = min((ll)maze[mx][my],now.val);
                qu.push(Node(mx,my,min(now.val,(ll)maze[mx][my])));
            }
        }
        // for(int i=0;i<n;i++) {
        //     for(int j=0;j<m;j++) if(maze[i][j] && vis[i][j]) res += maze[i][j];
        // }
        printf("%lld\n",res);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值