BZOJ 1104 [POI2007]洪水

描述

AKD 市处在一个四面环山的谷地里。最近一场大暴雨引发了洪水,AKD 市全被水淹没了。Blue Mary,AKD 市的市长,召集了他的所有顾问(包括你)参加一个紧急会议。经过细致的商议之后,会议决定,调集若干巨型抽水机,将它们放在某些被水淹的区域,而后抽干洪水。

你手头有一张 AKD 市的地图。这张地图是边长为 mn 的矩形,被划分为 mn个 11 的小正方形。对于每个小正方形,地图上已经标注了它的海拔高度以及它是否是 AKD 市的一个组成部分。地图上的所有部分都被水淹没了。并且,由于这张地图描绘的地面周围都被高山所环绕,洪水不可能自动向外排出。显然,我们没有必要抽干那些非 AKD 市的区域。

每个巨型抽水机可以被放在任何一个 1
1 正方形上。这些巨型抽水机将持续地抽水直到这个正方形区域里的水被彻底抽干为止。当然,由连通器原理,所有能向这个格子溢水的格子要么被抽干,要么水位被降低。每个格子能够向相邻的格子溢水,“相邻的”是指(在同一高度水平面上的射影)有公共边。

输入

第一行是两个数 m,n.

以下 m 行,每行 n 个数,其绝对值表示相应格子的海拔高度;若该数为正,表示他是 AKD 市的一个区域;否则就不是。

所有格子的海拔高度其绝对值不超过 1000,且可以为零.

输出

只有一行,包含一个整数,表示至少需要放置的巨型抽水机数目。

样例

Sample Input
6 9
-2 -2 -1 -1 -2 -2 -2 -12 -3
-2 1 -1 2 -8 -12 2 -12 -12
-5 3 1 1 -12 4 -6 2 -2
-5 -2 -2 2 -12 -3 4 -3 -1
-5 -6 -2 2 -12 5 6 2 -1
-4 -8 -8 -10 -12 -8 -6 -6 -4
Sample Output
2

提示

1<=m,n<=1000


这什么鬼翻译

ps.“相邻的”是指(在同一高度水平面上的射影)有公共边。 = “相邻的”是指与其它格子有公共边。

若在 I 放置一个抽水机,且 J 与 I 之间存在一条路径使得 路径中高度最大值<=hig[J],那么 J 的水可以被抽干。

我们用并查集来找城市的集合。

将格子按高度从小到大加入并查集,加入一个点时将它和它相邻的格子插入一个集合,

若某个点需要抽水且合并后没有它属于的集合抽水机则在它这里放置一个抽水机。

代码蒯上

#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
inline int gotcha()
{
register int _a=0;bool _b=1;register char _c=getchar();
while(_c<'0' || _c>'9'){if(_c=='-')_b=0;_c=getchar();}
while(_c>='0' && _c<='9')_a=_a*10+_c-48,_c=getchar();
return _b?_a:-_a;
}
const int _ = 1002,$ = 1000002;
int num[_][_],fa[$],hig[_][_],n,m;
bool ed[$]={0};
struct akd
{
int x,y,num;
const bool operator < (const akd &b)const
{return num<b.num;}
}d[$],c[$];
int finder(int a){return fa[a]<0?a:fa[a]=finder(fa[a]);}
void link(int a,int b)
{
a=finder(a),b=finder(b);
if(a==b)return;
fa[a]=b,ed[b]=max(ed[a],ed[b]);
}
int main()
{
memset(fa,-1,sizeof(fa));
register int i,j,k,x,y,cnt=0,akd_cnt=0,now=1,ans=0;
n=gotcha(),m=gotcha();
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
k=gotcha();
hig[i][j]=abs(k);
num[i][j]=++cnt;
d[cnt]=(akd){i,j,abs(k)};
if(k>0)c[++akd_cnt]=d[cnt];
}
sort(c+1,c+akd_cnt+1),sort(d+1,d+cnt+1);
for(i=1;i<=akd_cnt;i++)
{
while(now<=cnt && d[now].num<=c[i].num)
{
x=d[now].x,y=d[now].y;
if(x>1&&hig[x-1][y]<=hig[x][y])link(num[x][y],num[x-1][y]);
if(y>1&&hig[x][y-1]<=hig[x][y])link(num[x][y],num[x][y-1]);
if(x<n&&hig[x+1][y]<=hig[x][y])link(num[x][y],num[x+1][y]);
if(y<m&&hig[x][y+1]<=hig[x][y])link(num[x][y],num[x][y+1]);
now++;
}
x=c[i].x,y=c[i].y;
if(!ed[finder(num[x][y])])ed[finder(num[x][y])]=1,ans++;
}
printf("%d",ans);
return 0;
}

问题来了,抽掉的水去了哪儿呢?

并查集 - BZOJ 1104 [POI2007]洪水的更多相关文章

  1. 【BZOJ】1104: [POI2007]洪水pow

    题意 给一个\(n * m(1 \le n, m \le 1000)\)的矩阵,如果\(a_{i, j}\)为正表示城市.\(|a_{i, j}|(|a_{i, j}| \le 1000)\)是格子\ ...

  2. 线段树合并+并查集 || BZOJ 2733: [HNOI2012]永无乡 || Luogu P3224 [HNOI2012]永无乡

    题面:P3224 [HNOI2012]永无乡 题解: 随便写写 代码: #include<cstdio> #include<cstring> #include<iostr ...

  3. [POI2007]洪水pow 并查集

    我们先得出一个结论:水泵要建在城市上.因为如果在非城市上建能把其他一些城市抽干,那么在城市上建也是一个效果(自己画图感性理解一下) 然后我们明白抽水的条件:周围的高度要>=自身的高度,这样会抽完 ...

  4. BZOJ 1098 [POI2007]办公楼biu(反向图bfs+并查集优化)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1098 [题目大意] 现在有一张图,要求将这张图的点划分为尽量多的分组,对于不同分组的两 ...

  5. 【BZOJ】2049: [Sdoi2008]Cave 洞穴勘测(lct/并查集)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2049 bzoj挂了..在wikioi提交,,1A-写lct的速度越来越快了-都不用debug-- 新 ...

  6. 【BZOJ 1594】 [Usaco2008 Jan]猜数游戏 (二分+并查集)

    1594: [Usaco2008 Jan]猜数游戏 Description 为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力. 游戏开始前,一头指定的奶牛会在牛棚后面 ...

  7. BZOJ.4500.矩阵(差分约束 SPFA判负环 / 带权并查集)

    BZOJ 差分约束: 我是谁,差分约束是啥,这是哪 太真实了= = 插个广告:这里有差分约束详解. 记\(r_i\)为第\(i\)行整体加了多少的权值,\(c_i\)为第\(i\)列整体加了多少权值, ...

  8. BZOJ.2054.疯狂的馒头(并查集)

    BZOJ 倒序处理,就是并查集傻题了.. 并查集就是确定下一个未染色位置的,直接跳到那个位置染.然而我越想越麻烦=-= 以为有线性的做法,发现还是要并查集.. 数据随机线段树也能过去. //18400 ...

  9. BZOJ 4195: [Noi2015]程序自动分析 并查集+离散化

    LUOGU 1955BZOJ 4195 题目描述 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3...代表程序中出现的变量 ...

随机推荐

  1. SIGGRAPH 2017:深度学习与计算机图形学的碰撞

    每年由美国计算机协会(Association of Computing Machinery,简称ACM)计算机图形专业组举办的年会SIGGRAPH,是全球最负盛名的图形学和交互技术盛会.今年已经是这场 ...

  2. 为什么要用mallloc

    为什么要用malloc函数申请内存空间? 有的程序往往在运行时才知道要动态分配多大的内存,例如: void foo(char *str, int n) { char buf[?]; strncpy(b ...

  3. SQL Server 2016,2014 “无法找到数据库引擎启动句柄”

    当我决定安装SharePoint 2016 IT预览版时,我想我应该将它安装在Windows Server 2016技术预览版以及SQL Server 2016社区技术预览版(CTP)上.我敢打赌,你 ...

  4. Vijos P1243 生产产品 (单调队列优化DP)

    题意: 必须严格按顺序执行M个步骤来生产一个产品,每一个步骤都可以在N台机器中的任何一台完成.机器i完成第j个步骤的时间为T[i][j].把半成品从一台机器上搬到另一台机器上也需要一定的时间K.每台机 ...

  5. HDU 2639 Bone Collector II (01背包,第k解)

    题意: 数据是常规的01背包,但是求的不是最大容量限制下的最佳解,而是第k佳解. 思路: 有两种解法: 1)网上普遍用的O(V*K*N). 2)先用常规01背包的方法求出背包容量限制下能装的最大价值m ...

  6. LibreOJ #2003. 「SDOI2017」新生舞会

    内存限制:256 MiB 时间限制:1500 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: 匿名 01分数规划(并不知道这是啥..) km或费用流(并不会)验证 屠龙宝刀点击就送 ...

  7. Unity中的各种寻找GameObject方法归纳

    1.GameObject.Find():寻找Hierarchy面板中的activie 不为false的游戏对象: 路径如官方事例写法: public class ExampleClass : Mono ...

  8. js中读取解析json数据

    在数据传输流程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象,所以,JSON对象和JSON字符串之间的相互转换是关键. JSON字符串:       'var str1 = ' ...

  9. vector 下标操作

    比如:vector<int> ivec(3).. 当采用下标操作ivec[10]的时候,该操作是未定义的,在自己的机器上输出的值是零.建议使用迭代器进行操作.

  10. vs 2012打开vs2013的sln

    Project -> Properties -> General -> Platform Toolset (as IInspectable correctly commented)