ICPC NEAU Programming Contest 2020 L. 城市排水(優先隊列bfs)

思路: 實際上是用已經確定水位高度的點去更新還沒有確定高度的點。一開始有坑的點的水位高度就是方塊高度。每次取當前最小水位高度的點去更新其他點,就可以保證每個點只需要更新一次。

本題中邊界無限高,所以不用管邊界的影響(更新完就是無窮大)。假設沒有邊界或者邊界高度爲0,那麼同理可以看作已經確定邊界水位高度了,把邊界入堆即可。

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <queue>
#include <cmath>

using namespace std;

const int maxn = 505;

struct Node {
    int x,y,h;
    bool operator < (const Node&rhs) const {
        return h > rhs.h;
    }
};
int n,m;
int mxh[maxn][maxn],h[maxn][maxn];
int dirx[] = {0,0,-1,1};
int diry[] = {1,-1,0,0};

priority_queue<Node>q;

void bfs() {
    while(!q.empty()) {
        Node now = q.top();q.pop();
        int x = now.x,y = now.y,H = now.h;
        
        for(int d = 0;d < 4;d++) {
            int dx = x + dirx[d];
            int dy = y + diry[d];
            if(dx < 1 || dy < 1 || dx > n || dy > n) continue;
            if(mxh[dx][dy]) continue;
            
            mxh[dx][dy] = max(h[dx][dy],mxh[x][y]);
            
            q.push({dx,dy,mxh[dx][dy]});
        }
    }
}

int main() {
    int T;scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&n,&m);
        for(int i = 1;i <= n;i++) {
            for(int j = 1;j <= n;j++) {
                scanf("%d",&h[i][j]);
                mxh[i][j] = 0;
            }
        }
        
        for(int i = 1;i <= m;i++) {
            int x,y;scanf("%d%d",&x,&y);
            mxh[x][y] = h[x][y];
            q.push({x,y,mxh[x][y]});
        }
        
        bfs();
        
        for(int i = 1;i <= n;i++) {
            for(int j = 1;j <= n;j++) {
                printf("%d ",mxh[i][j] - h[i][j]);
            }
            printf("\n");
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章