洛谷P3457 [POI2007]POW-The Flood

題目鏈接

題意翻譯

Description 你手頭有一張該市的地圖。這張地圖是邊長爲 m∗n 的矩形,被劃分爲m∗n個1∗1的小正方形。對於每個小正方形,地圖上已經標註了它的海拔高度以及它是否是該市的一個組成部分。地圖上的所有部分都被水淹沒了。並且,由於這張地圖描繪的地面周圍都被高山所環繞,洪水不可能自動向外排出。顯然,我們沒有必要抽乾那些非該市的區域。

每個巨型抽水機可以被放在任何一個1∗1正方形上。這些巨型抽水機將持續地抽水直到這個正方形區域裏的水被徹底抽乾爲止。當然,由連通器原理,所有能向這個格子溢水的格子要麼被抽乾,要麼水位被降低。每個格子能夠向相鄰的格子溢水,“相鄰的”是指(在同一高度水平面上的射影)有公共邊。

Input

第一行是兩個數m,n(1<=m,n<=1000).

以下 m 行,每行 n 個數,其絕對值表示相應格子的海拔高度;若該數爲正,表示它是該市的一個區域;否則就不是。

請大家注意:所有格子的海拔高度其絕對值不超過 1000 ,且可以爲零.

Output

只有一行,包含一個整數,表示至少需要放置的巨型抽水機數目。

題目描述

Byteburg, the capital of Byteotia, is a picturesque city situated in a valley in the midst of mountains. Unfortunately, recent heavy rainfall has caused a flood - all the Byteburg is now completely under water. Byteasar, the king of Byteotia, has summoned his most enlightened advisors, including you, to a council. After long deliberations the council agreed to bring a few pumps, set them up in the flooded area and drain Byteburg.

The king has asked you to determine the minimum number of pumps sufficing to drain the city.

You are provided with a map of the city and the valley it is situated in. The map is in the shape of a m×nm\times nm×n rectangle, divided into unitary squares. For each such square the map tells its height above sea level and alsowhether it is a part of Byteburg or not. The whole area depicted in the map is under water. Furthermore, it issurrounded by much higher mountains, making the outflow of water impossible. Obviously, there is no needto drain the area that does not belong to Byteburg.

Each pump can be placed in any unitary square depicted in the map. The pump will be drawing thewater until its square is completely drained. Of course, the communicating tubes principle makes its work, so draining one square results in lowering the water level or complete draining of those squares from which the water can flow down to the one with the pump. Water can flow only between squares with a common side (or, more exact, squares whose projections onto horizontal plane have a common side, since the squares may be at different level). Apart from that, the water obviously only flows down.
Task

Write a programme that:

reads description of the map from the standard input,

determines the minimum number of pumps needed to drain whole Byteburg,
writes out the outcome to the standard output.

給定一張地勢圖,所有的點都被水淹沒,現在有一些關鍵點,要求放最少的水泵使所有關鍵點的水都被抽乾

輸入輸出格式

輸入格式:

In the first line of the standard input there are two integers mmm and nnn , separated by a single space, 1≤n,m≤1 0001 \le n, m \le 1\ 0001≤n,m≤1 000 . The following mmm lines contain the description of the map. The (i+1)(i+1)(i+1) ‘th line describes the iii ‘th row of unitary squares in the map. It contains nnn integers xi,1,xi,2,…,xinx_{i,1}, x_{i,2}, …, x_{i_n}xi,1​,xi,2​,…,xin​​ , separated by single spaces,−1 000≤xi,j≤1 000-1\ 000 \le x_{i,j} \le 1\ 000−1 000≤xi,j​≤1 000 ,xi,j≠1000x_{i,j} \ne 1000xi,j​≠1000 . The number xi,jx_{i,j}xi,j​ describes the jjj ‘th square of the iii ‘th line. The ground level in this square is ∣xi,j∣|x_{i,j}|∣xi,j​∣ above sea level. If xi,j>0x_{i,j} > 0xi,j​>0 , then the square is part of Byteburg, otherwise it is outside the city. Notice, that the area of Byteburg need not be connected. In fact the city may have several separate parts.

輸出格式:

Your programme should write out one integer to the standard output - the minimum number of pumpsneeded to drain Byteburg.

輸入輸出樣例:
輸入樣例#1:

6 9
-2 -2 -1 -1 -2 -2 -2 -12 -3
-2 1 -1 2 -8 -12 2 -12 -12
-5 3 1 1 -12 4 -6 2 -2
-5 -2 -2 2 -12 -3 4 -3 -1
-5 -6 -2 2 -12 5 6 2 -1
-4 -8 -8 -10 -12 -8 -6 -6 -4

輸出樣例#1:
2

樣例說明:
這裏寫圖片描述

題意解析:
若在I放置一個抽水機,且J與I之間存在一條路徑使得max(H)<=H[j],那麼J的水可以被抽乾。

算法:並查集

  1. 先將所有點按高度排序。
  2. 枚舉每個點,並將它 相鄰的點且高度<=這個點的高度 的點與它合併。假設:這個點是a[i], 有一個滿足 相鄰的點且高度<=這個點的高度 這一條件的點a[j],很明顯a[i]的水可以流向a[j], 所以如果a[j]的水已經被抽水機抽完了,那麼a[i]的水也會被抽完。
  3. 判斷該點是否爲城市。如果不爲城市,則不需要抽水機。如果爲城市且該聯通塊內沒有抽水機,則在該城市放一個抽水機。(注意:這裏必須先將同一高度的點都合併了才能判斷)

    爲什麼必須先將同一高度的點都合併了才能判斷呢?

    例如數據:
    1 4
    3 3 2 1

    很明顯答案是1
    我們來模擬一下,排完序後,數據可能會變爲
    1 2 3 3(第3個 ‘3’爲 原來序列的第1個)
    那麼邊做時邊判斷是否有抽水機
    到第3個3時 聯通塊爲: 1-2 3 就要用兩個抽水機了

完整代碼:

#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int a[N][N];
struct node
{
    int x, y, h;
    bool operator <(const node &z)const
    {
        return h<z.h;
    }
}p[N*N];
int pl;
int fa[N*N], num[N][N], s[N*N];
int find(int x)
{
    if(fa[x] == x) return x;
    return fa[x] = find(fa[x]);
}
int mov[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
void hb(int x, int y)
{
    int X = find(x), Y = find(y);
    s[Y] |= s[X];
    fa[X] = Y;
    /*這裏要注意了,不能是fa[Y] = X。 
    如果是fa[Y] = X, 那麼前面應改成s[X] |= s[Y]。
    假如, Y集合中有抽水機, X集合中沒有。
    按
        s[Y] |= s[X];
        fa[Y] = X;
    那麼合併後 s[Y] = 1, s[X] = 0。
    如果是
    則find(Y) = X
    s[X] = 0, 所以集合中沒有抽水機。
    然而,這個集合是有抽水機的。
    */
    return ;
}
int main()
{
    int n, m, ans = 0;
    scanf("%d%d", &n, &m);
    memset(a, 127, sizeof(a));
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            scanf("%d", &a[i][j]);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
        {
            num[i][j] = pl;
            p[++pl] = (node){i, j, abs(a[i][j])};
        }
    sort(p+1, p+1+pl);
    for(int i = 1; i <= pl; i++)
        fa[i] = i;
    for(int i = 1; i <= pl; i++)
    {
        int X = p[i].x, Y = p[i].y;
        for(int j = 0; j < 4; j++)
        {
            int x = X + mov[j][0], y = Y + mov[j][1];
            if(abs(a[x][y]) <= p[i].h)
                hb(num[x][y], num[X][Y]);
        }
        if(p[i].h != p[i+1].h)
            for(int j = i; p[j].h == p[i].h; j--)
                if(a[p[j].x][p[j].y]>0)
                {
                    int x = find(num[p[j].x][p[j].y]);
                    if(!s[x])
                        s[x] = 1, ans++;
                }
    }
    printf("%d\n", ans);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章