有一种神奇的算法叫做floodfill

就是一个n*m的矩阵,a[i][j]为当前高度,我们可以任选一个点倒水,开始bfs,如果要搜的点没有被搜到过,并且高度小于当前的点,我们就把这个点加入队列中

而这道题我们可以用floodfill做

先假设有解,也就是说假设干旱区里的所有城区都能建水利措施。

对于第一行湖泊,显然我们bfs往下floodfill覆盖的最后一行肯定是个区间,那么对于第一行两个点floodfill后覆盖的最后一行的两个区间,如果左边端点floodfill的右边一部分与右边端点floodfill的左边一部分有相交部分,那么这两个floodfill最后一行所覆盖的区间的左端点肯定是相同的,但是我们选择建蓄水厂肯定是选择右边端点,因为右边端点的floodfill能够多覆盖一部分。

所以我们从左往右枚举最后一行的端点,从最后一行的端点先倒着做一遍floodfill,所覆盖的第一行的区间中选择最右边的端点,再正着做一遍floodfill,直接标记floodfill中扫到的最后一行的区间里的端点,再把这个区间的右端点的右边一个点进行倒着做一遍floodfill......就这样循环做下去直到(n,m)被标记

那么怎么判断无解呢?显然,我们把第一行所有端点都做一遍正着的floodfill,也就是说能建蓄水厂的都建起来。再统计最后一行的没被标记的点数,如果有被标记的,就按照无解的输出形式输出,否则就是有解,按照有解的办法解决问题

可能解释有些不清,可以线下找我)

那么就是我们的代码,其中booms函数是正着floodfill,boom函数是倒着floodfill

Code:

#include<iostream>
#include<cstdio>
using namespace std;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int n,m,a[10001][10001];
bool vis[10001][10001];
bool viss[10001][10001];
int qx[400001],qy[400001];
int ans;
int boom(int p)
{
int tail=1,head=1;
vis[n][p]=1;
qx[1]=n;
qy[1]=p;
while(head<=tail)
{
int x=qx[head],y=qy[head];
head++;
for(int i=0;i<4;i++)
{
int tx=x+dx[i],ty=y+dy[i];
if(tx>=1&&ty>=1&&tx<=n&&ty<=m&&!vis[tx][ty]&&a[x][y]<a[tx][ty])
{
qx[++tail]=tx;
qy[tail]=ty;
vis[tx][ty]=1;
}
}
}
for(int i=m;i>=1;i--)
if(vis[1][i])
return i;
return 0;
}
void booms(int p)
{
int tail=1,head=1;
qx[1]=1;
qy[1]=p;
viss[1][p]=1;
while(head<=tail)
{
int x=qx[head],y=qy[head];
head++;
for(int i=0;i<4;i++)
{
int tx=x+dx[i],ty=y+dy[i];
if(tx>=1&&ty>=1&&tx<=n&&ty<=m&&!viss[tx][ty]&&a[x][y]>a[tx][ty])
{
qx[++tail]=tx;
qy[tail]=ty;
viss[tx][ty]=1;
}
}
}
}
inline int read()
{
int r=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') w=~w+1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
r=(r<<3)+(r<<1)+ch-(1<<4)-(1<<5);
ch=getchar();
}
return r*w;
}
int main()
{
//freopen("P1514_5.in","r",stdin);
n=read();m=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
a[i][j]=read();
for(int i=1;i<=m;i++)
booms(i);
ans=0;
for(int i=1;i<=m;i++)
if(!viss[n][i])
ans++;
if(ans){
cout<<0<<endl<<ans;
return 0;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
vis[i][j]=viss[i][j]=0;
int right=1;
while(!viss[n][m]&&!vis[n][m])
{
int x=boom(right);
booms(x);
for(int i=m;i>=1;i--)
if(!viss[n][i])
right=i;
ans++;
}
cout<<1<<endl<<ans;
return 0;
}

题解 Luogu P1514 【引水入城】的更多相关文章

  1. [luogu]P1514 引水入城[搜索][记忆化][DP]

    [luogu]P1514 引水入城 引水入城 题目描述在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形 ,如下图所示,其中每个格 ...

  2. 【luogu P1514 引水入城】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1514 // luogu-judger-enable-o2 #include <iostream> ...

  3. Luogu P1514 引水入城

    我承认我有点懒(洛谷已经发过题解了,但我发誓要坚持写博客) 这道题坑了我3天…… 首先一看就与染色问题类似,果断BFS(写DFS炸了) 先将最上面(靠近水)的一行全部扔进队列里,做一遍BFS 再对最下 ...

  4. Luogu P1514引水入城【搜索】 By cellur925

    题目传送门 这道题开始看好像并没有什么思路,和搜索好像也并没有什么关系.但是我们手玩下样例就会发现,思路其实就三句话:(写这道题的时候在代码里写的) //我们想知道从第1行的每列往下到干旱区的范围 / ...

  5. [NOIp2010] luogu P1514 引水入城

    跟 zzy, hwx 等人纠结是否回去上蛋疼的董老板的课. 题目描述 如图所示.你有一个 N×MN\times MN×M 的矩阵,水可以从一格流到与它相邻的格子,需要满足起点的海拔严格高于终点海拔.定 ...

  6. LUOGU P1514 引水入城 (bfs)

    传送门 解题思路 拉了很长的战线,换了好几种写法终于过了..首先每个蓄水场一定是对沙漠造成连续一段的贡献,所以可以$bfs$出每种状态,然后做一次最小区间覆盖,但这样的复杂度有点高.就每次只搜那些比左 ...

  7. Luogu 1514 引水入城 (搜索,动态规划)

    Luogu 1514 引水入城 (搜索,动态规划) Description 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N行M列的矩形,如上图 ...

  8. 洛谷P1514 引水入城

    洛谷P1514 引水入城 原题链接 一道好题...细节真多 第一次提交90分,然后就GG了,不知从何改起 其实比较简单吧... 首先,一个点的水流向最后一排,一定可以形成一个区间. 不行的话肯定GG ...

  9. 洛谷 P1514 引水入城 解题报告

    P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个 NN 行 \times M×M 列的矩形,如上图所示,其中每个格 ...

  10. CODEVS 1066/洛谷 P1514引水入城

    1066 引水入城 2010年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description 在一个遥远的国 ...

随机推荐

  1. 【初学】Spring源码笔记之零:阅读源码

    笔记要求 了解Java语言 了解Spring Framework的基础 会使用Maven 关于本笔记 起因 本职数据分析,为公司内部人员开发数据处理系统,使用了Python/Django+Bootst ...

  2. python positional argument follows keyword argument

    关键字参数必须跟随在位置参数后面! 因为python函数在解析参数时, 是按照顺序来的, 位置参数是必须先满足, 才能考虑其他可变参数.

  3. Tableau如何嵌入HTML

    原文地址:https://blog.csdn.net/read_you2011/article/details/81476108 作者:read_you2011 说明 作为领先的数据可视化工具,Tab ...

  4. 证明:ThreadLocal的get,set方法无法防止内存泄漏

    先给出结论:get,set两个方法都不能完全防止内存泄漏,还是每次用完ThreadLocal都勤奋的remove一下靠谱. 前言:   看到有的博客说在把ThreadLocal的所有强引用置空前,调用 ...

  5. 学Python常用数据结构之字典

    迄今为止,我们已经为大家介绍了Python中的三种容器型数据类型,但是这些数据类型还不足以帮助我们解决所有的问题.例如,我们要保存一个人的信息,包括姓名.年龄.体重.单位地址.家庭住址.本人手机号.紧 ...

  6. 集训作业 洛谷P1101 单词方阵

    这个题的长度真的有点长,我直接放图片吧 这个题又是一个和谐的搜索,找到yizhong的y就开始8面搜索,遇见正确的字母就继续搜索,不正确就果断放弃,果然又是一个和谐的搜索呢. #include< ...

  7. 数据聚合与分组操作知识图谱-《利用Python进行数据分析》

    所有内容整理自<利用Python进行数据分析>,使用MindMaster Pro 7.3制作,emmx格式,源文件已经上传Github,需要的同学转左上角自行下载或者右击保存图片. 其他章 ...

  8. 【Nginx】图片显示过慢,文件下载不完全,竟然是Nginx的锅!!

    写在前面 最近,一名读者跟我说他通过浏览器访问自己的服务器时,图片显示的非常慢,以至于在浏览器中都无法完全加载出来,下载文件时,更是恼火,文件根本就无法完全下载下来.而且奇怪的是这位读者所在的网络是没 ...

  9. python-在python3中使用容联云通讯发送短信验证码

    容联云通讯是第三方平台,能够提供短信验证码和语音通信等功能,这里只测试使用短信验证码的功能,因此只需完成注册登录(无需实名认证等)即可使用其短信验证码免费测试服务,不过免费测试服务只能给控制台中指定的 ...

  10. 离线安装 docker

    1.基础环境 操作系统:CentOS 7.8 docker 版本:18.06.1 2.docker 下载 2.1 官方地址 https://download.docker.com/linux/stat ...