Luogu345: [POI2007]POW-The Flood

Posted Cyhlnj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu345: [POI2007]POW-The Flood相关的知识,希望对你有一定的参考价值。

题意

见luogu

Sol

贪心
从小到大枚举高度,把小于等于这一高度的相邻格子用并查集合并
那么这个集合内的所有格子都一定可以由这个集合内的一个最低点抽完水
那么合并之后(一定要在合并之后)
判断这一高度是否有城市,有则检查它所在的集合是否放了抽水机,没有就在这个集合中放一个

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
# define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
using namespace std;
typedef long long ll;
const int _(1005);

IL int Input(){
    RG int x = 0, z = 1; RG char c = getchar();
    for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x * z;
}

int n, m, ans, h[_][_], id[_][_], cnt, type[_][_], done[_ * _];
int que[_ * _];
int fa[_ * _], dx[4] = {1, -1}, dy[4] = {0, 0, 1, -1};
struct Data{
    int x, y, id;

    IL bool operator <(RG Data B) const{
        return h[x][y] < h[B.x][B.y];
    }
} p[_ * _];

IL int Find(RG int x){
    return fa[x] == x ? x : fa[x] = Find(fa[x]);
}

IL void Union(RG int Sx, RG int Sy, RG int fx){
    for(RG int i = 0; i < 4; ++i){
        RG int xx = Sx + dx[i], yy = Sy + dy[i];
        if(xx < 1 || yy < 1 || xx > n || yy > m || h[xx][yy] > h[Sx][Sy]) continue;
        RG int fy = Find(id[xx][yy]); fx = Find(fx);
        if(fx == fy) continue;
        done[fx] |= done[fy], fa[fy] = fx;
    }
}

int main(RG int argc, RG char* argv[]){
    n = Input(), m = Input();
    for(RG int i = 1; i <= n; ++i)
        for(RG int j = 1; j <= m; ++j){
            h[i][j] = Input(), type[i][j] = h[i][j] > 0;
            if(!type[i][j]) h[i][j] = -h[i][j];
            id[i][j] = ++cnt, fa[cnt] = cnt, p[cnt] = (Data){i, j, cnt};
        }
    sort(p + 1, p + cnt + 1);
    for(RG int i = 1, now; i <= cnt; ++i){
        if(h[p[i].x][p[i].y] != now){
            while(que[0]){
                RG int x = Find(que[que[0]--]);
                if(!done[x]) done[x] = 1, ++ans;
            }
            now = h[p[i].x][p[i].y];
        }
        Union(p[i].x, p[i].y, p[i].id);
        if(type[p[i].x][p[i].y]) que[++que[0]] = p[i].id;
    }
    while(que[0]){
        RG int x = Find(que[que[0]--]);
        if(!done[x]) done[x] = 1, ++ans;
    }
    printf("%d\n", ans);
    return 0;
}

以上是关于Luogu345: [POI2007]POW-The Flood的主要内容,如果未能解决你的问题,请参考以下文章

Luogu3455POI2007ZAP-Queries(莫比乌斯反演)

luogu P3455 [POI2007]ZAP-Queries

luogu3455 [POI2007]ZAP-Queries 简单的莫比乌斯反演

[POI2007]ATR-Tourist Attractions

BZOJ1101 & 洛谷3455:[POI2007]ZAP——题解

poi