NOIP2010 引水入城 贪心+DFS
我们先把简单的不能搞死,具题意可证:每个蓄水长的管辖区域一定是连续的。
证明:既然我们已经能了那么我们就可以说如果这个区间不是连续的那我们取出这个区间中间阻隔开的那一段,那么对于这一整个区间来说水源不可能来自两边那么一定至少有一条直通蓄水厂的路连其上一点,那么对于连着的那个蓄水厂a,以及我们造成此区间的蓄水厂b,b一定不是a,b若在a的左边则无法到达右边,若b在a的右边则无法到达左边,因此移动是连续的。由于数据中有一个一行的(既邻水又临漠),我要说一下,对于这个结论显然成立。
那么我们既然知道了每个蓄水厂的管辖范围我们进行右端点贪心即可。
#include<cstdio>
#include<bitset>
#include<algorithm>
#include<vector>
#define N 505
using namespace std;
inline int read()
{
int sum=;
char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')
{
sum=(sum<<)+(sum<<)+ch-'';
ch=getchar();
}
return sum;
}
struct Tr
{
int to,next;
}c[N*N*];
int head[N*N],t,kin[N*N];
bool v[N*N];
bitset<N> ctr[N];
int n,m;
int h[N][N];
inline int get(int x,int y)
{
return (x-)*m+y;
}
inline void add(int x,int y)
{
c[++t].to=y;
c[t].next=head[x];
head[x]=t;
}
void Init()
{
n=read(),m=read();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
h[i][j]=read();
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
{
if(h[i+][j]<h[i][j]&&i+<=n)add(get(i,j),get(i+,j));
if(h[i-][j]<h[i][j]&&i->)add(get(i,j),get(i-,j));
if(h[i][j+]<h[i][j]&&j+<=m)add(get(i,j),get(i,j+));
if(h[i][j-]<h[i][j]&&j->)add(get(i,j),get(i,j-));
}
for(int i=;i<=m;i++)
kin[get(,i)]=,kin[get(n,i)]=;
}
int hol=;
void jud(int x)
{
if(v[x])return;
if(kin[x]==)hol++;
v[x]=;
for(int i=head[x];i;i=c[i].next)
jud(c[i].to);
}
bool Jud()
{
for(int i=;i<=m;i++)
jud(i);
if(hol<m)
{
printf("");
printf("\n");
printf("%d\n",m-hol);
return ;
}
return ;
}
bool over[N];
int vo[N*N];
void dfs(int x,int now)
{
if(vo[x]==now)return;
vo[x]=now;
if(kin[x]==&&x!=now)
over[x]=;
if(kin[x]==)
ctr[now][x-(n-)*m]=;
for(int i=head[x];i;i=c[i].next)
dfs(c[i].to,now);
}
struct DP
{
int l,r;
}dp[N];
int Min,ans,NN=;
int bre[N];
bool Now[N];
int comp(const DP a,const DP b)
{
return a.l<b.l;
}
void Dp()
{
NN--;
sort(dp+,dp+NN+,comp);
int now=,Ans=;
for(int i=;i<=NN;i++)
{
if(dp[i].l>now)
{
ans++;
now=Ans+;
if(now>m)break;
}
if(dp[i].r>Ans)
Ans=dp[i].r;
}
if(now<=m)
ans++;
}
void work()
{
for(int i=;i<=m;i++)
if(!over[i])
dfs(i,i);
for(int i=;i<=m;i++)
if(!over[i])
bre[++Min]=i;
for(int i=;i<=Min;i++)
{
int no=;
for(int j=;j<=m;j++)
{
if(no==&&ctr[bre[i]][j]==)
{
no=;
dp[NN].l=j;
}
if(no==&&ctr[bre[i]][j]==)
{
dp[NN].r=j-;
break;
}
}
if(no==)
{
i--;
Min--;
continue;
}
if(dp[i].r==)
dp[NN].r=m;
NN++;
}
Dp();
printf("");
printf("\n");
printf("%d\n",ans);
}
int main()
{
Init();
if(Jud())return ;
work();
return ;
}
NOIP2010 引水入城 贪心+DFS的更多相关文章
- NOIP2010引水入城[BFS DFS 贪心]
题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个海拔高度. ...
- [NOIP2010] 引水入城 贪心 + 记忆化搜索
---题面--- 题解: 本蒟蒻并没有想到bfs的做法,,,, 只会dfs了 首先我们需要知道一个性质. 我们设k[i].l 为在i点建立水库可以支援到的最左边的城市,k[i].r为最右边的. 那么点 ...
- 521. [NOIP2010] 引水入城 cogs
521. [NOIP2010] 引水入城 ★★★ 输入文件:flow.in 输出文件:flow.out 简单对比时间限制:1 s 内存限制:128 MB 在一个遥远的国度,一侧是风景秀 ...
- NOIP2010 引水入城
4引水入城 题目描述 在一个遥远的国度,一侧是风景秀美的湖泊,另一侧则是漫无边际的沙漠.该国的行政区划十分特殊,刚好构成一个N 行M 列的矩形,如上图所示,其中每个格子都代表一座城市,每座城市都有一个 ...
- noip2010 引水入城 bfs+贪心
如果能够实现,每个河边的城市对应的控制区域一定是一条线段. 所以直接bfs每个河边的城市,贪心线段的右端点 #include<cstdio> #include<cstring> ...
- Luogu1514 NOIP2010 引水入城 BFS、贪心
传送门 NOIP的题目都难以写精简题意 考虑最上面一排的某一个点对最下面一排的影响是什么样的,不难发现必须要是一段连续区间才能够符合题意. 如果不是一段连续区间,意味着中间某一段没有被覆盖的部分比周围 ...
- NOIP2010 引水入城 题解
http://www.rqnoj.cn/problem/601 今天发现最小区间覆盖竟然是贪心,不用DP!于是我又找到这题出来撸了一发. 要找到最上面每个城市分别能覆盖最下面哪些城市,如果最下面有城市 ...
- noip2010引水入城
https://www.zybuluo.com/ysner/note/1334997 这道题fst了 题面 戳我 解析 我一开始的想法是,按照高度给第一行排序,然后贪心地选取目前到不了的,高度最高的第 ...
- noip 2010 引水入城 贪心 + 搜索
不难分析出如果有解则每个蓄水厂所能覆盖到的干旱城市一定是连续的.否则,中间那些没被覆盖的部分永远都不能被覆盖到. 当然,每个蓄水厂所覆盖的城市有可能不连续,不过既然有解,则一定都是连续的.我们可以开一 ...
随机推荐
- hadoop生态搭建(3节点)-07.hive配置
# http://archive.apache.org/dist/hive/hive-2.1.1/ # ================================================ ...
- backtrace函数
1.函数原型 #include <execinfo.h> int backtrace(void **buffer, int size); 该函数获取当前线程的调用堆栈,获取的信息将会被存放 ...
- CSS3新特性回顾
CSS3 介绍 开始实例 新特征简介 强大的CSS选择器 抛弃图片的视觉效果 盒模型变化(多列布局和弹性盒模型) 阴影效果 Web字体和web Font 图标 CSS33过渡与动画交互效果 媒体查询 ...
- Mysql自学笔记
SQL(strucut query language) DDL (数据库定义语言)DML (数据库操作语言)DCL (数据库的控制语言)DTL (数据库的高级语言)查看版本的函数select vers ...
- Android ImageSwitcher 配合Picasso解决内存溢出(OOM)问题
最近项目中用到了 ImageSwitcher 来实现图片切换,使用起来很简单,但发现当图片比较大(超过了3M)时,程序出现了内存溢出(OOM)问题而崩溃了. 原因就是图片太大了,显示到 ImageVi ...
- 关于相对布局RelativeLayout的各种属性介绍
RelativeLayout相对布局是个人觉得在android布局中比较常用且好用的一个,当然如果想让布局更漂亮是需要多种布局混合搭建的,这里就需要更深入的学习了,在这只介绍下有关相对布局的东西. 相 ...
- Qt 在控件上面绘图 label,pushbutton。。。。。
最近有点时间,就研究研究Qt ,提升一下自己 我记得我在刚开始学习Qt 的时候,想要在一个控件上面绘制图形,那就要构建一个新类来调用该控件的绘图函数 今天看到了狗哥的学习博客,感觉自己好渺小啊,按照狗 ...
- 第三十四篇 Python面向对象之 反射(自省)
什么是反射? 反射的概念是由Smith在1982年提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语 ...
- 第二十篇 sys模块
修改环境变量 import sys sys.path.append() 但是,这种修复方式只是临时修改 如果要永久修改,就要电脑里配置环境变量. sys.argv:命令行参数List,第一个元素是程序 ...
- Uniy 组件式泛型单例模式
我们知道,在Unity中,所有对象脚本都必须继承MonoBehavior脚本,才能使用Unity内置的脚本功能; 通常我们可以用静态类来取代单例模式,但是静态类方法的缺点是,它们必须继承最底层的类-- ...