博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
noip2010 引水入城 - bfs + 贪心
阅读量:5213 次
发布时间:2019-06-14

本文共 2719 字,大约阅读时间需要 9 分钟。

题目描述

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

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

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

输入输出格式

输入格式:

 

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

 

输出格式:

 

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

 

 

题解

先对于每一个沿湖城市做一遍bfs, 求出从那个城市出发能够到达的沙漠旁的城市的区间, 若不是一段区间, 则必定不能全部覆盖, 做完bfs后可以直接判断。

接着再贪心区间覆盖, 求出最少的区间数, 即为答案

 

 

 

代码

1 #include
2 #include
3 #include
4 #include
5 #define rd read() 6 #define rep(i,a,b) for( int i = (a); i <= (b); ++i ) 7 #define per(i,a,b) for( int i = (a); i >= (b); --i ) 8 using namespace std; 9 typedef pair
P;10 11 queue

q;12 13 const int N = 505, inf = 1061109567;14 15 int n, m, h[N][N], vis[N][N], ok[N], tot ;16 17 int dx[4] = { 0, 0, -1, 1}, dy[4] = { 1, -1, 0, 0};18 19 struct node {20 int l, r;21 }ln[N];22 23 int read() {24 int X = 0, p = 1; char c = getchar();25 for(; c > '9' || c < '0'; c = getchar() ) if( c == '-' ) p = -1;26 for(; c >= '0' && c <= '9'; c = getchar() ) X = X * 10 + c - '0';27 return X * p;28 }29 30 void bfs( int x ) {31 memset(vis, 0, sizeof(vis));32 q.push( P( 1, x ) );33 vis[1][x] = 1;34 ln[x].l = n + 1, ln[x].r = 0;35 if( n == 1 && !ok[x] ) {36 ok[x] = 1;37 tot++;38 ln[x].l = x;39 ln[x].r = x;40 }41 for( P u, to; !q.empty(); ) {42 u = q.front(); q.pop();43 for( int i = 0; i < 4; ++i ) {44 int nx = u.first + dx[i], ny = u.second + dy[i];45 if( !nx || !ny || nx > n || ny > m || vis[nx][ny]) continue;46 if( h[nx][ny] >= h[u.first][u.second] ) continue;47 vis[nx][ny] = 1;48 if( nx == n ) {49 ln[x].l = min( ln[x].l, ny);50 ln[x].r = max( ln[x].r, ny);51 if( !ok[ny] ) ok[ny] = 1, tot++;52 }53 q.push( P( nx, ny ) );54 }55 }56 }57 58 int cmp( const node &A, const node &B ) {59 return A.l == B.l ? A.r < B.r : A.l < B.l;60 }61 62 int main()63 {64 n = rd, m = rd;65 rep( i, 1, n ) rep( j, 1, m ) h[i][j] = rd;66 rep( i, 1, m ) if( h[1][i] >= h[1][i - 1] && h[1][i] >= h[1][i + 1]) bfs( i );67 if( tot != m ) return printf("0\n%d\n", m - tot), 0;68 sort(ln + 1, ln + 1 + m, cmp);69 int l = 1, r = 1, ans = 0, now = 1;70 for(; r <= m; ) {71 for(; ln[now].l <= r && now <= m; now++ ) l = max( l, ln[now].r );72 ans++;73 r = l + 1;74 }75 printf("1\n%d\n", ans);76 }

View Code

 

转载于:https://www.cnblogs.com/cychester/p/9467592.html

你可能感兴趣的文章
eclipse安装wtp
查看>>
(转)C#中属性PropertyInfo的使用,Dictionary转为Model实例
查看>>
2017NOIP游记
查看>>
学习yii2.0框架阅读代码(二)
查看>>
Windows Apache2.4 配置https/SSL
查看>>
PHP常用魔术方法(__call魔术方法:)
查看>>
vue 工作学习总结
查看>>
REST总结
查看>>
Hibernate中的session和load延迟载入矛盾问题,怎样解决?
查看>>
log4j:WARN Please initialize the log4j system properly解决的方法
查看>>
《Google软件测试之道》测试工程师
查看>>
1. 决策树python源码实现--多叉分类树
查看>>
mac设置终端命令行别名alias(git、npm)
查看>>
阅读计划
查看>>
树(基本概念及存储结构)
查看>>
python Flask 学前班
查看>>
【转】FreeType介绍
查看>>
简明扼要kvm安装
查看>>
Proxy模式(代理[延迟]模式)
查看>>
Docker最全教程之树莓派和Docker(十五)
查看>>