我们先把简单的不能搞死,具题意可证:每个蓄水长的管辖区域一定是连续的。
证明:既然我们已经能了那么我们就可以说如果这个区间不是连续的那我们取出这个区间中间阻隔开的那一段,那么对于这一整个区间来说水源不可能来自两边那么一定至少有一条直通蓄水厂的路连其上一点,那么对于连着的那个蓄水厂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的更多相关文章

  1. NOIP2010引水入城[BFS DFS 贪心]

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

  2. [NOIP2010] 引水入城 贪心 + 记忆化搜索

    ---题面--- 题解: 本蒟蒻并没有想到bfs的做法,,,, 只会dfs了 首先我们需要知道一个性质. 我们设k[i].l 为在i点建立水库可以支援到的最左边的城市,k[i].r为最右边的. 那么点 ...

  3. 521. [NOIP2010] 引水入城 cogs

    521. [NOIP2010] 引水入城 ★★★   输入文件:flow.in   输出文件:flow.out   简单对比时间限制:1 s   内存限制:128 MB 在一个遥远的国度,一侧是风景秀 ...

  4. NOIP2010 引水入城

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

  5. noip2010 引水入城 bfs+贪心

    如果能够实现,每个河边的城市对应的控制区域一定是一条线段. 所以直接bfs每个河边的城市,贪心线段的右端点 #include<cstdio> #include<cstring> ...

  6. Luogu1514 NOIP2010 引水入城 BFS、贪心

    传送门 NOIP的题目都难以写精简题意 考虑最上面一排的某一个点对最下面一排的影响是什么样的,不难发现必须要是一段连续区间才能够符合题意. 如果不是一段连续区间,意味着中间某一段没有被覆盖的部分比周围 ...

  7. NOIP2010 引水入城 题解

    http://www.rqnoj.cn/problem/601 今天发现最小区间覆盖竟然是贪心,不用DP!于是我又找到这题出来撸了一发. 要找到最上面每个城市分别能覆盖最下面哪些城市,如果最下面有城市 ...

  8. noip2010引水入城

    https://www.zybuluo.com/ysner/note/1334997 这道题fst了 题面 戳我 解析 我一开始的想法是,按照高度给第一行排序,然后贪心地选取目前到不了的,高度最高的第 ...

  9. noip 2010 引水入城 贪心 + 搜索

    不难分析出如果有解则每个蓄水厂所能覆盖到的干旱城市一定是连续的.否则,中间那些没被覆盖的部分永远都不能被覆盖到. 当然,每个蓄水厂所覆盖的城市有可能不连续,不过既然有解,则一定都是连续的.我们可以开一 ...

随机推荐

  1. PHP-提升PHP性能的几个扩展

    下面介绍的几个扩展原理都是对OPCODE进行缓存(Opcode缓存原理查看http://www.cnblogs.com/JohnABC/p/4531029.html): Zend Opcache: 由 ...

  2. 为什么不早点使用 Git...

    教程:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000/0013739628770 ...

  3. 第一次学习tornado小练习

    内容 这次是python的一个web框架,tornado,这个web框架在python的几个web框架中一个比较简单的web框架,刚开始接触python的时候就知道python有两个比较常用的web框 ...

  4. Tomcat+nginx+keepalived+memcached实现双VIP负载均衡及Session会话保持

    准备好tomcat 第一台 tar vxf apache-tomcat-7.0.54.tar.gz mv apache-tomcat-7.0.54 /usr/local/tomcat tar vxf ...

  5. Ubuntu装完后要做的几件事

    Ubuntu装完后要做的几件事 改hosts 无论哪里,改hosts都是第一件事,没hosts咋google.没google咋活.在终端输入命令 sudo gedit /etc/hosts在# The ...

  6. linux文件操作篇 (一)文件属性与权限

    文件的属性和权限是linux中 目录 和 文件 的两个基本特性. #属性: . 所有者属性 . 访问权限属性   -rwxrwxr-x #第一个字符是文件类别 -表示 普通文件 d 表示目录 b 表示 ...

  7. R语言学习笔记(三):零碎知识点(1-10)

    1--c() c表示"连接"(concatenate). 在R中向量是连续存储的,因此不能插入或删除元素. 2--seq() seq()的特殊用法,可以用在for循环里for(i ...

  8. P1107 最大整数

    P1107 最大整数 题目描述 设有n个正整数 (n<=20), 将它们连接成一排, 组成一个最大的多位整数. 例如: n=3时, 3个整数13, 312, 343连接成的最大整数为: 3433 ...

  9. Android Studio 使用小结

    从去年(2013年5月)Google发布Android Studio 0.1.0版本,到如今已经一年多了,已经升级到0.8.6 Beta版 ,从刚开始大家报怨bug多,编译困难,到如今已经基本趋于稳定 ...

  10. 自动化测试(一)-get和post的简单应用

    今天主要介绍两种测试的接口post和get: get和post是http的两种基本请求方式,区别在于get把参数包含在url中传递:给而post把参数以json或键值对的方式利用工具传递. get的传 ...