P1514 引水入城 DFS
题目描述
在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠。该国的行政区划十分特殊,刚好构成一个NN 行\times M×M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度。
为了使居民们都尽可能饮用到清澈的湖水,现在要在某些城市建造水利设施。水利设施有两种,分别为蓄水厂和输水站。蓄水厂的功能是利用水泵将湖泊中的水抽取到所在城市的蓄水池中。
因此,只有与湖泊毗邻的第11 行的城市可以建造蓄水厂。而输水站的功能则是通过输水管线利用高度落差,将湖水从高处向低处输送。故一座城市能建造输水站的前提,是存在比它海拔更高且拥有公共边的相邻城市,已经建有水利设施。由于第NN 行的城市靠近沙漠,是该国的干旱区,所以要求其中的每座城市都建有水利设施。那么,这个要求能否满足呢?如果能,请计算最少建造几个蓄水厂;如果不能,求干旱区中不可能建有水利设施的城市数目。
输入输出格式
输入格式:
每行两个数,之间用一个空格隔开。输入的第一行是两个正整数N,MN,M,表示矩形的规模。接下来NN 行,每行MM个正整数,依次代表每座城市的海拔高度。
输出格式:
两行。如果能满足要求,输出的第一行是整数11,第二行是一个整数,代表最少建造几个蓄水厂;如果不能满足要求,输出的第一行是整数00,第二行是一个整数,代表有几座干旱区中的城市不可能建有水利设施。
输入输出样例
3 6
8 4 5 6 4 4
7 3 4 3 3 3
3 2 2 1 1 2
1
3 非常好的一道搜索题目
贪心+DFS即可解决 这题DFS很简单 主要是后期处理
#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define REP(i,N) for(int i=0;i<(N);i++)
#define CLR(A,v) memset(A,v,sizeof A)
//////////////////////////////////
#define inf 0x3f3f3f3f
#define N 5005
int n,m;
int mp[N][N];
int vis[N][N];
int vis2[N];
int ri[N];
vector<int>node[N];//该城市所到达的点
vector<int>in[N];//到达该点的城市
bool inmap(int x,int y)
{
return x>=&&x<=n&&y>=&&y<=m;
}
int dx[]={,,,-};
int dy[]={,-,,};
void dfs(int x,int y,int flag)
{
if(x==n)
{
node[flag].push_back(y);
ri[flag]=max(ri[flag],y);
in[y].push_back(flag);
vis2[y]=;
}
rep(i,,)
{
int a=x+dx[i];
int b=y+dy[i];
if(!inmap(a,b))continue;
if(vis[a][b]==flag)continue;
if(mp[a][b]>=mp[x][y])continue;
vis[a][b]=flag;
dfs(a,b,flag);
}
}
struct aaa
{
int id,h;
}s[N];
bool cmp(aaa a,aaa b)
{
return a.h>b.h;
}
int main()
{
RII(n,m);
rep(i,,n)
rep(j,,m)
{
RI(mp[i][j]);
if(i==)
s[j].id=j,s[j].h=mp[i][j];
}
sort(s+,s++m,cmp);//贪心优化 高的先来 剪了30ms。。。 rep(i,,m)
if(!vis[][ s[i].id ])
dfs(,s[i].id,s[i].id); int ok=;
int cnt=;
rep(i,,m)
if(!vis2[i])ok=,cnt++;
if(!ok)printf("%d\n%d",,cnt);
else
{
printf("1\n"); int sum=;
int i=;
while(i<=m)
{
int maxx=;
rep(j,,in[i].size()-)
maxx=max(maxx, ri[ in[i][j] ] ); sum++;
i=maxx+;
}
cout<<sum;
}
return ;
}
大佬的做法 速度比我的快一倍QAQ 递归求左界和右界非常巧妙
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <stack>
using namespace std;
#define maxn 510
#define nx x+xx[i]
#define ny y+yy[i]
int l[maxn][maxn],r[maxn][maxn];
int high[maxn][maxn];
int n,m;
bool vis[maxn][maxn];
int xx[]={-,,,};
int yy[]={,,,-};
int qx[maxn*maxn],qy[maxn*maxn]; inline void dfs(int x,int y)
{
vis[x][y]=true;
for (int i=;i<;i++){
if (nx< || nx>n || ny< || ny>m) continue;
if (high[nx][ny]>=high[x][y]) continue;
if (!vis[nx][ny])dfs(nx,ny);
l[x][y]=min(l[x][y],l[nx][ny]);
r[x][y]=max(r[x][y],r[nx][ny]);
}
} inline int read()
{
int ret=;
char c=getchar();
while (c<'' || c>'') c=getchar();
while (c>='' && c<=''){
ret=ret*+c-'';
c=getchar();
}
return ret;
} int main()
{
n=read();
m=read();
memset(vis,false,sizeof(vis));
memset(l,0x3f,sizeof(l));
memset(r,,sizeof(r));
for (int i=;i<=m;i++)
l[n][i]=r[n][i]=i;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
high[i][j]=read();
for (int i=;i<=m;i++)
if (!vis[][i]) dfs(,i);
bool flag=false;
int cnt=;
for (int i=;i<=m;i++)
if (!vis[n][i]){
flag=true;
cnt++;
}
if (flag){
puts("");
printf("%d",cnt);
return ;
}
int left=;
while (left<=m){
int maxr=;
for (int i=;i<=m;i++)
if (l[][i]<=left)
maxr=max(maxr,r[][i]);
cnt++;
left=maxr+;
}
puts("");
printf("%d",cnt);
}
P1514 引水入城 DFS的更多相关文章
- 洛谷P1514 引水入城——dfs
题目:https://www.luogu.org/problemnew/show/P1514 搜索+DP: 自己想出来的方法第一次80分好高兴! 再改了改就A了,狂喜乱舞: 也就是 dfs,仔细一想第 ...
- 洛谷P1514 引水入城
洛谷P1514 引水入城 原题链接 一道好题...细节真多 第一次提交90分,然后就GG了,不知从何改起 其实比较简单吧... 首先,一个点的水流向最后一排,一定可以形成一个区间. 不行的话肯定GG ...
- 洛谷 P1514 引水入城 解题报告
P1514 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个 NN 行 \times M×M 列的矩形,如上图所示,其中每个格 ...
- [luogu]P1514 引水入城[搜索][记忆化][DP]
[luogu]P1514 引水入城 引水入城 题目描述在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形 ,如下图所示,其中每个格 ...
- CODEVS 1066/洛谷 P1514引水入城
1066 引水入城 2010年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在一个遥远的国 ...
- 洛谷P1514 引水入城 [搜索,区间DP]
题目传送门 引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个 N 行×M 列的矩形,如上图所示,其中每个格子都代表一座城市,每 ...
- 【luogu P1514 引水入城】 题解
题目链接:https://www.luogu.org/problemnew/show/P1514 // luogu-judger-enable-o2 #include <iostream> ...
- P1514 引水入城
概述 首先,这是一道好题,这道题既考查了图论的dfs知识,又考察了区间贪心问题中很典型的区间覆盖问题,着实是一道好题. 大概思路说明 我们观察到,只有第一行可以放水库,而第一行在哪里放水库的结果就是直 ...
- Luogu P1514 引水入城
我承认我有点懒(洛谷已经发过题解了,但我发誓要坚持写博客) 这道题坑了我3天…… 首先一看就与染色问题类似,果断BFS(写DFS炸了) 先将最上面(靠近水)的一行全部扔进队列里,做一遍BFS 再对最下 ...
随机推荐
- 基于MVC 的Quartz.Net组件实现的定时执行任务调度
新建mvc项目之后,首先引用Quartz组件.工具-->NuGet包管理器-->管理解决方案的 NuGet包管理器 组件安装完成. Quartz.Net一个最简单任务至少包括三部分实现:j ...
- windows连接服务端的域名正常,linux却不通,(针对于负载均衡后端节点设置)
1.初步判断不是网络上的,因为windows主机访问正常, 2.修改客户端linux主机 net.ipv4.tcp_tw_recycle=0,测试是否正常,(服务器当连接数达到一定量之后,会执行rec ...
- iOS -- Effective Objective-C 阅读笔记 (2)
1: 多用类型常量, 少用 #define 预处理指令 #define 预处理指令会把碰到的所有 指定名称 一律换位 定义的内容, 这样的话, 假设此指令在某个头文件中, 那么所有引入这个头文件的代码 ...
- 开源中国社区 https://git.oschina.net/ 添加 SSH 公钥 添加
首先可以参考官方的帮助文档 http://git.mydoc.io/?t=154712 然后进去码云首页 http://git.oschina.net 然后找到右边的头像点击一下 然后点击修改资料 ...
- linux之iptables常用命令
iptables详解 iptables -L 该命令会以列表的形式显示出当前使用的 iptables 规则,每一条规则前面的编号可以用来做为其它操作--例如删除操作--的参数,很有用 iptables ...
- C#概念总结(五)
1.C#特性 (Attribute) 特性适用于在运行时传递程序中的各中元素(比如 类.方法.结构.枚举.组件)的行为信息额声明性标签,可以通过使用特性向程序添加声明性信息,一个声明标签是通过放置在他 ...
- kali linux DVWA config 问题解决方案
1.下载DVWA之后解压到 var/www/html目录下 unzip DVWA-master.zip -d /usr/www/html 2.配置 打开终端,执行以下命令: 将apache2停止:se ...
- java提取出一个字符串里面的Double类型数字
String str="hh\n1\n22\n798.809\n0.89\n"; String regex="\\d+(?:\\.\\d+)?" ...
- AI-认证
AI-认证 做登录验证 #models.py class Users(models.Model): user=models.CharField(max_length=32) pwd=models.Ch ...
- js call() 笔记
var ctrl = function() {}; ctrl.view = function() { return { show: function() { console.log("vie ...