zoukankan      html  css  js  c++  java
  • 洛谷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
    %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
    %d", ans);
    101     return 0;
    102 }
    洛谷P1514
  • 相关阅读:
    【转】myeclipse中连接mysql数据库
    struts2入门示例(hello world)
    【转】MyEclipse第一个Servlet程序
    学习马士兵的struts2/hibernate/spring中遇到的问题及其解决方法
    typeof关键字
    SHLVL--shell终端深度
    stack
    queue
    getopt--parse command line options
    怎样实时判断socket连接状态?
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7663213.html
Copyright © 2011-2022 走看看