P1514 water into the city [search segment covering]

Title Description

In a distant country, a scenic lake side, the other side is endless desert. Administrative divisions of the country is very special, just constitute a \ (N \) line \ (M \) rectangular columns, as shown above, where each grid represents a city, every city has a height above sea level.
In order to make the residents have to drink as much as possible to clear lake, now to build irrigation facilities in some cities. There are two water conservancy facilities, namely water plants and water stations. Water plant pump function is to use the lake water drawn into the city's reservoir.
Therefore, only the lake next to the city in the first row can build water plant. The function of the station is to use water drop height by a water pipeline, the water delivered from the heights to the flat. So the city can build a water station premise is the existence of higher and have a common edge adjacent to the city than its altitude, has built water conservancy facilities. Since the N-th row of the city close to the desert, arid region of the country, it requires each of which cities have built irrigation facilities. Well, we can meet this requirement? If so, please calculate the minimum built several water plant; if not, impossible to find in arid regions has a number of urban water conservancy facilities.

Input Format

Each row two numbers, separated by a space between. Two first line of input is a positive integer N, MN, M, represents the size of the rectangle. Next NN lines of MM positive integers, followed by representatives of altitude each city.

Output Format

Two lines. If they can meet the requirements, the output of the first line is an integer of 11, the second line is an integer representing the minimum number of storage plant construction; if not meet the requirements, the output of the first line is an integer of 00, the second line is an integer , representatives of several cities in the arid region can not be built irrigation facilities.

Obviously if we can meet the requirements, each point can cover the top of the city must be a contiguous range. Otherwise, the intermediate portion can not be disconnected covered.
For the first line of each point to do it again BFS, seized interval for each point can be covered easily solve the first question.
For the point of the first row of the BFS search time can be skipped over, while the attention judgment \ (N = 1 \) the case where
the second line segment can be done asking covered with greedy strategy.

#include<bits/stdc++.h>
#define pii pair<int,int>
using namespace std;

int vis[505][505],cover[505],l[505],r[505],cnt,num[505];
int n,m,ma[505][505];
int mx[4] = {-1,1,0,0},
    my[4] = {0,0,-1,1};
bool cmp(int a,int b){
    if(l[a] < l[b]) return 1;
    if(l[a] > l[b]) return 0;
    return r[a] < r[b];
}
bool check(int xx,int yy){
    if(xx > 0 && xx <= n && yy > 0 && yy <= m) return true;
    return false;
}
void bfs(int k){
    memset(vis,0,sizeof(vis));
    queue<pii> q;
    q.push(make_pair(1,k));
    vis[1][k] = 1;
    if(n == 1) cover[k] = 1;
    while(!q.empty()){
        int x = q.front().first,y = q.front().second;
        q.pop();
        for(int i = 0; i < 4; ++i){
            int xx = x + mx[i],yy = y + my[i];
            if(vis[xx][yy]) continue;
            if(check(xx,yy) && ma[xx][yy] < ma[x][y]){
                vis[xx][yy] = 1;
                q.push(make_pair(xx,yy));
                if(xx == n) {
                    cover[yy] = 1;
                }
            }
        }
    }
    int flag = 0;
    for(int i = 1; i <= m; ++i){
        if(vis[n][i] && !flag) {
            flag = 1;
            l[cnt] = i;
        }
        if(vis[n][i] && flag){
            r[cnt] = max(r[cnt],i);
        }   
    }
}

int main(){
    memset(l,0x3f,sizeof(l));
    cin >> n >> m;
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= m; ++j){
            scanf("%d",&ma[i][j]);
        }
    for(int i = 1; i <= m; ++i){
        if(!vis[1][i]){
            ++cnt;
            bfs(i);
        }
    }
    int lack = 0;
    for(int i = 1; i <= m; ++i) if(!cover[i]) {
        lack++;
    }
    if(lack){
        cout << 0 << endl << lack << endl;
        return 0;
    }
    cout << 1 << endl;
    for(int i = 1; i <= m; ++i) num[i] = i;
    sort(num + 1,num + cnt + 1);
    int minn = 0x3f3f3f3f;
    int now = 0,ans = 0,to = 0;
    for(int i = 1; i <= cnt; ++i){
        if(now + 1 >= l[num[i]])
            to = max(to,r[num[i]]);
        else{
            ans++;
            now = to;
            to = max(to,r[num[i]]);
        }
    }
    if(now != m) ans++;
    cout << ans << endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/FoxC/p/11484302.html