Luogu1514 NOIP2010T4 引水入城 BFS、贪心

传送门

NOIP的题目都难以写精简题意


考虑最上面一排的某一个点对最下面一排的影响是什么样的,不难发现必须要是一段连续区间才能够符合题意。

如果不是一段连续区间,意味着中间某一段没有被覆盖的部分比周围都要高(因为当前这一个点的流域一定会覆盖到这一个部分的上面和左右两边),这表示这有一段区间是无论什么水流都无法流到的,所以就是无解了。

我们知道影响范围是一段区间之后,通过BFS把所有区间求出来,就是一个经典的线段覆盖问题了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int m[501][501] , x , y , dir[4][2] = {0,1,0,-1,1,0,-1,0};
 4 bool allVis[501] , vis[501][501];
 5 struct qj{
 6     int l , r;
 7 }ans[501];
 8 bool cmp(qj a , qj b){return a.l < b.l;}
 9 inline int min(int a , int b){return a < b ? a : b;}
10 inline int max(int a , int b){return a > b ? a : b;}
11 int main(){
12     scanf("%d%d" , &x , &y);
13     for(int i = 1 ; i <= x ; i++)
14         for(int j = 1 ; j <= y ; j++)
15             scanf("%d" , &m[i][j]);
16     for(int i = 1 ; i <= y ; i++){
17         memset(vis , 0 , sizeof(vis));
18         ans[i].l = 501;    ans[i].r = -1;
19         if((i == 1 || m[1][i] >= m[1][i - 1]) && (i == y || m[1][i] >= m[1][i + 1])){
20             queue < pair < int , int > > q;
21             q.push(make_pair(1 , i));
22             while(!q.empty()){
23                 pair < int , int > t = q.front();
24                 q.pop();
25                 if(t.first == x){
26                     ans[i].l = min(ans[i].l , t.second);
27                     ans[i].r = max(ans[i].r , t.second);
28                     allVis[t.second] = 1;
29                 }
30                 for(int j = 0 ; j < 4 ; j++)
31                     if(t.first + dir[j][0] > 0 && t.first + dir[j][0] <= x)
32                         if(t.second + dir[j][1] > 0 && t.second + dir[j][1] <= y)
33                             if(!vis[t.first + dir[j][0]][t.second + dir[j][1]])
34                                 if(m[t.first + dir[j][0]][t.second + dir[j][1]] < m[t.first][t.second]){
35                                     vis[t.first + dir[j][0]][t.second + dir[j][1]] = 1;
36                                     q.push(make_pair(t.first + dir[j][0] , t.second + dir[j][1]));
37                                 }
38             }
39         }
40     }
41     for(int i = 1 ; i <= y ; i++)
42         if(!allVis[i]){
43             int cnt = 1;
44             for(int j = i + 1 ; j <= y ; j++)
45                 cnt += !allVis[j];
46             cout << 0 << endl << cnt;
47             return 0;
48         }
49     sort(ans + 1 , ans + y + 1 , cmp);
50     int r = 1 , num = 0 , dir = 1;
51     while(r <= y){
52         num++;
53         int newR = 0;
54         while(dir <= y && ans[dir].l <= r)    newR = max(newR , ans[dir++].r + 1);
55         r = newR;
56     }
57     cout << 1 << endl << num;
58     return 0;
59 }

猜你喜欢

转载自www.cnblogs.com/Itst/p/9852280.html
今日推荐