洛谷P1514 [NOIP2010提高组T4]引水入城

Posted 嘒彼小星

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1514 [NOIP2010提高组T4]引水入城相关的知识,希望对你有一定的参考价值。

P1514 引水入城

题目描述

在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠。该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度。

技术分享

为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施。水利设施有两种,分别为蓄水厂和输水站。蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中。

因此,只有与湖泊毗邻的第1 行的城市可以建造蓄水厂。而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向低处输送。故一座城市能建造输水站的前提,是存在比它海拔更高且拥 有公共边的相邻城市,已经建有水利设施。由于第N 行的城市靠近沙漠,是该国的干旱区,所以要求其中的每座城市都建有水利设施。那么,这个要求能否满足呢?如果能,请计算最少建造几个蓄水厂;如果不能,求 干旱区中不可能建有水利设施的城市数目。

输入输出格式

输入格式:

输入文件的每行中两个数之间用一个空格隔开。输入的第一行是两个正整数N 和M,表示矩形的规模。接下来N 行,每行M 个正整数,依次代表每座城市的海拔高度。

输出格式:

输出有两行。如果能满足要求,输出的第一行是整数1,第二行是一个整数,代表最少建造几个蓄水厂;如果不能满足要求,输出的第一行是整数0,第二行是一个整数,代表有几座干旱区中的城市不可能建有水利设施。

输入输出样例

输入样例#1:
【输入样例1】
2 5
9 1 5 4 3
8 7 6 1 2

【输入样例2】
3 6
8 4 5 6 4 4
7 3 4 3 3 3
3 2 2 1 1 2
输出样例#1:
【输出样例1】
1
1

【输出样例2】
1
3

说明

【样例1 说明】

只需要在海拔为9 的那座城市中建造蓄水厂,即可满足要求。

【样例2 说明】

技术分享

上图中,在3 个粗线框出的城市中建造蓄水厂,可以满足要求。以这3 个蓄水厂为源头

在干旱区中建造的输水站分别用3 种颜色标出。当然,建造方法可能不唯一。

【数据范围】

技术分享

 

【题解】

第一次bfs判断可行性

第二次bfs得到每个点能灌溉到的底部区间

可以证明有解当且仅当每个点覆盖到的区间时连续的

然后变成了区间覆盖的贪心

按左端点排序,每次选右端点最远的那一个

hwzer的贪心骚操作秒啊!

易错:

为了在dfs中对l,r进行处理,把l赋值为INF,导致

贪心时出错,应及时退出

 

技术分享
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <queue>
  7 #define min(a, b) ((a) < (b) ? (a) : (b))
  8 #define max(a, b) ((a) > (b) ? (a) : (b))
  9 
 10 inline void swap(int &x, int &y)
 11 {
 12     long long tmp = x;x = y;y = tmp;
 13 }
 14 
 15 inline void read(int &x)
 16 {
 17     x = 0;char ch = getchar(), c = ch;
 18     while(ch < 0 || ch > 9)c = ch, ch = getchar();
 19     while(ch <= 9 && ch >= 0)x = x * 10 + ch - 0, ch = getchar();
 20     if(c == -)x = -x;
 21 }
 22 
 23 const int INF = 0x3f3f3f3f;
 24 const int MAXN = 600 + 10;
 25 const int dx[4] = {1,0,-1,0};
 26 const int dy[4] = {0,1,0,-1};
 27 
 28 struct Node
 29 {
 30     int l, r;
 31     Node(int _l, int _r){l = _l;r = _r;}
 32     Node(){l = INF;r = 0;} 
 33 }node[MAXN][MAXN];
 34 
 35 int n,m,g[MAXN][MAXN],b[MAXN][MAXN],ans;
 36 
 37 //可行性判断 
 38 void dfs1(int x, int y)
 39 {
 40     b[x][y] = 1;
 41     for(register int i = 0;i < 4;++i)
 42     {
 43         int xx = x + dx[i], yy = y + dy[i];
 44         if(xx <= 0 || yy <= 0 || xx > n || yy > m || b[xx][yy] || g[xx][yy] >= g[x][y])continue;
 45         dfs1(xx, yy);
 46     }
 47 }
 48 
 49 void dfs(int x, int y)
 50 {
 51     b[x][y] = 1;
 52     if(x == n)node[x][y].l = min(node[x][y].l, y), node[x][y].r = max(node[x][y].r, y);
 53     for(register int i = 0;i < 4;++ i)
 54     {
 55         int xx = x + dx[i], yy = y + dy[i];
 56         if(xx <= 0 || yy <= 0 || xx > n || yy > m || g[xx][yy] >= g[x][y])continue;
 57         if(b[xx][yy])
 58         {
 59             node[x][y].l = min(node[x][y].l, min(node[xx][yy].l, yy));
 60             node[x][y].r = max(node[x][y].r, max(node[xx][yy].r, yy));
 61             continue;
 62         }
 63         dfs(xx, yy);
 64         node[x][y].l = min(node[x][y].l, min(node[xx][yy].l, yy));
 65         node[x][y].r = max(node[x][y].r, max(node[xx][yy].r, yy));
 66     }
 67 }
 68 
 69 int cmp(Node a, Node b)
 70 {
 71     return a.l == b.l ? a.r < b.r : a.l < b.l;
 72 }
 73 
 74 int main()
 75 {
 76     read(n), read(m);
 77     for(register int i = 1;i <= n;++ i)
 78         for(register int j = 1;j <= m;++ j)
 79             read(g[i][j]);
 80     for(register int i = 1;i <= m;++ i)
 81         if(!b[1][i])dfs1(1,i);
 82     for(register int i = 1;i <= m;++ i)
 83         if(!b[n][i])
 84             ++ ans;
 85     if(ans)
 86     {
 87         printf("0\n%d", ans);
 88         return 0;
 89     }
 90     memset(b, 0, sizeof(b));
 91     for(register int i = 1;i <= m;++ i)
 92         if(!b[1][i])
 93             dfs(1, i);
 94     std::sort(node[1] + 1, node[1] + 1 + m, cmp);
 95     int far = 0, now = 0;
 96     for(register int i = 1;i <= m && now < m;++ i)
 97         if(node[1][i].l <= now + 1)far = max(far,node[1][i].r);
 98         else now = far, far = max(far, node[1][i].r), ++ans;
 99     if(now != m)++ ans;
100     printf("1\n%d", ans);
101     return 0;
102 }
洛谷P1514

 

 

 

以上是关于洛谷P1514 [NOIP2010提高组T4]引水入城的主要内容,如果未能解决你的问题,请参考以下文章

CODEVS 1066/洛谷 P1514引水入城

记忆化搜索+dp(洛谷1514 引水入城2010noip提高组)

洛谷 P1514 引水入城

洛谷P1514 引水入城

luoguP1514 引水入城 题解(NOIP2010)

[洛谷P1514]引水入城