I - Ivan and the swimming pool Gym - 102448I(二分+bfs)

After another great year for UFPE’s competitive programming team, the coach Ivan decided to gift the team and invest in building a pool at an area nearby. After reuniting with the group to arrange the details, four things were decided:

The pool must have size S.
It cannot have separate parts.
All areas of the pool must be equally deep.
It has to be as deep as possible.
There was only one limitation stopping us from always digging deeper: Rocks. Because of rocks underground, it wouldn’t be possible to dig more than a certain depth in each part of the area.

To help us pick the best place for the pool, we split the area in cells, measured how deep we could dig in each of them and mapped it into a grid, such as the one shown below:

97787897
To help us estimate the costs of the building, you must calculate the maximum possible depth of the pool.

Input
S, N and M, the size of the pool and the dimensions of the terrain. Followed by N lines with M integers on each, the depth of each cell on the area.

1≤N, M≤106, S≤N⋅M≤106, 1≤ Depths ≤108
Output
D, the maximum depth of the pool.

Examples
Input
1 2 4
9 7 7 9
7 8 8 7
Output
9
Input
2 2 4
9 7 7 9
7 8 8 7
Output
8
Input
3 2 4
9 7 7 9
7 8 8 7
Output
7
Note
In the case presented on the statement, for a pool of size 1, we could choose one of the 9 units deep cells to have a 9 units deep pool.

For a pool of size 2 however, the deepest it could be is 8 units, by choosing both cells with 8 units deep. Because the 9 units deep cells aren’t connected and combining one of them with a 7 units deep cell would make the entire pool 7 units deep.

For all other sizes, you must use at least one 7 deep cell to keep the pool connected, so the pool would be 7 units deep.

題意:
找到一個大小爲s的連通塊,使得最小值最大

思路:
有單調性,然後二分,沒了

#include <cstdio>
#include <map>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

const int maxn = 1e6 + 7;

int dirx[] = {1,-1,0,0};
int diry[] = {0,0,1,-1};
vector<vector<int> >a;
vector<vector<bool> >vis;
map<int,int>mp;
vector<int>dat;
int n,m,s;

int bfs(int x,int y,int mid) {
    queue<pair<int,int> >q;
    q.push({x,y});
    int res = 1;
    vis[x][y] = 1;
    while(!q.empty()) {
        pair<int,int> now = q.front();q.pop();
        for(int d = 0;d < 4;d++) {
            int dx = now.first + dirx[d];
            int dy = now.second + diry[d];
            if(dx < 0 || dy < 0 || dx >= n || dy >= m) continue;
            if(vis[dx][dy]) continue;
            if(a[dx][dy] < mid) continue;
            vis[dx][dy] = 1;
            res++;
            q.push({dx,dy});
        }
    }
    return res;
}

bool check(int mid) {
    vis.resize(n);
    for(int i = 0;i < n;i++) {
        vis[i].resize(m);
        for(int j = 0;j < m;j++) {
            vis[i][j] = false;
        }
    }
    for(int i = 0;i < n;i++) {
        for(int j = 0;j < m;j++) {
            if(vis[i][j] == false) {
                if(a[i][j] >= mid) {
                    int num = bfs(i,j,mid);
                    if(num >= s) return true;
                }
            }
        }
    }
    return false;
}

int main() {
    scanf("%d%d%d",&s,&n,&m);
    for(int i = 0;i < n;i++) {
        vector<int>now;
        for(int j = 0;j < m;j++) {
            int x;scanf("%d",&x);
            if(!mp[x]) {
                mp[x] = 1;
                dat.push_back(x);
            }
            now.push_back(x);
        }
        a.push_back(now);
    }
    
    sort(dat.begin(),dat.end());
    int l = 0,r = dat.size() - 1;
    int ans = 0;
    while(l <= r) {
        int mid = (l + r) >> 1;
        if(check(dat[mid])) {
            l = mid + 1;
            ans = mid;
        } else {
            r = mid - 1;
        }
    }
    
    printf("%d\n",dat[ans]);
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章