并查集 - BZOJ 1104 [POI2007]洪水
BZOJ 1104 [POI2007]洪水
描述
AKD 市处在一个四面环山的谷地里。最近一场大暴雨引发了洪水,AKD 市全被水淹没了。Blue Mary,AKD 市的市长,召集了他的所有顾问(包括你)参加一个紧急会议。经过细致的商议之后,会议决定,调集若干巨型抽水机,将它们放在某些被水淹的区域,而后抽干洪水。
你手头有一张 AKD 市的地图。这张地图是边长为 mn 的矩形,被划分为 mn个 11 的小正方形。对于每个小正方形,地图上已经标注了它的海拔高度以及它是否是 AKD 市的一个组成部分。地图上的所有部分都被水淹没了。并且,由于这张地图描绘的地面周围都被高山所环绕,洪水不可能自动向外排出。显然,我们没有必要抽干那些非 AKD 市的区域。
每个巨型抽水机可以被放在任何一个 11 正方形上。这些巨型抽水机将持续地抽水直到这个正方形区域里的水被彻底抽干为止。当然,由连通器原理,所有能向这个格子溢水的格子要么被抽干,要么水位被降低。每个格子能够向相邻的格子溢水,“相邻的”是指(在同一高度水平面上的射影)有公共边。
输入
第一行是两个数 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]洪水的更多相关文章
- 【BZOJ】1104: [POI2007]洪水pow
题意 给一个\(n * m(1 \le n, m \le 1000)\)的矩阵,如果\(a_{i, j}\)为正表示城市.\(|a_{i, j}|(|a_{i, j}| \le 1000)\)是格子\ ...
- 线段树合并+并查集 || BZOJ 2733: [HNOI2012]永无乡 || Luogu P3224 [HNOI2012]永无乡
题面:P3224 [HNOI2012]永无乡 题解: 随便写写 代码: #include<cstdio> #include<cstring> #include<iostr ...
- [POI2007]洪水pow 并查集
我们先得出一个结论:水泵要建在城市上.因为如果在非城市上建能把其他一些城市抽干,那么在城市上建也是一个效果(自己画图感性理解一下) 然后我们明白抽水的条件:周围的高度要>=自身的高度,这样会抽完 ...
- BZOJ 1098 [POI2007]办公楼biu(反向图bfs+并查集优化)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1098 [题目大意] 现在有一张图,要求将这张图的点划分为尽量多的分组,对于不同分组的两 ...
- 【BZOJ】2049: [Sdoi2008]Cave 洞穴勘测(lct/并查集)
http://www.lydsy.com/JudgeOnline/problem.php?id=2049 bzoj挂了..在wikioi提交,,1A-写lct的速度越来越快了-都不用debug-- 新 ...
- 【BZOJ 1594】 [Usaco2008 Jan]猜数游戏 (二分+并查集)
1594: [Usaco2008 Jan]猜数游戏 Description 为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力. 游戏开始前,一头指定的奶牛会在牛棚后面 ...
- BZOJ.4500.矩阵(差分约束 SPFA判负环 / 带权并查集)
BZOJ 差分约束: 我是谁,差分约束是啥,这是哪 太真实了= = 插个广告:这里有差分约束详解. 记\(r_i\)为第\(i\)行整体加了多少的权值,\(c_i\)为第\(i\)列整体加了多少权值, ...
- BZOJ.2054.疯狂的馒头(并查集)
BZOJ 倒序处理,就是并查集傻题了.. 并查集就是确定下一个未染色位置的,直接跳到那个位置染.然而我越想越麻烦=-= 以为有线性的做法,发现还是要并查集.. 数据随机线段树也能过去. //18400 ...
- BZOJ 4195: [Noi2015]程序自动分析 并查集+离散化
LUOGU 1955BZOJ 4195 题目描述 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3...代表程序中出现的变量 ...
随机推荐
- 字符串和byte数组的相互转化
关于byte[]数组转十六进制字符串: public static String getHexString(byte[] b) throws Exception { String result = & ...
- w3c万维网的介绍和html基本构成
怎么与浏览器交互? 1.鼠标 2.键盘输入 w3c标准: 中文名:万维网联盟!外文名:world wide web cansortium万维网联盟创建于1994年,是web技术领域最具权威个影响的国际 ...
- MUI获取文本框的值
MUI事件绑定注意父节点.子节点(也可以是标签选择器) js部分 html部分
- 如何从桌面程序向浏览器传递cookie或自定义header
类似问题 从c#程序启动ie并传递cookie 打开默认浏览器并传递cookie 打开一个web浏览器使用c#应用程序并添加请求头 猜想 从wpf程序打开默认浏览器并定位到一个url ,并且向这个ur ...
- UVA 11134 FabledRooks 传说中的车 (问题分解)
摘要:贪心,问题分解. 因为行列无关,所以这个二维问题可以分解成两个一维问题. 优先队列实现:类似区间点覆盖的问题,先按照左端点排序,相同然后在按右端点排序(灵活性小的优先选).最优的选法,当然是要使 ...
- 2017年团体程序设计天梯赛 - 大区赛 L3-3
题意:有向图找哈密顿回路 比赛的时候剪枝只剪了vis 状压没剪对 反而只拿17分... 比赛结束后还去看了一发这个NP问题的QB(快速回溯法...但是对于本题好像大材小用...) 上网看了一个神犇的写 ...
- mysql如何让自增id从1开始设置方法
有两种方式 第一种: 如果表中数据没有用.如果直接删除数据,自动增长ID还是不会从1开始的,可以利用“清空数据表”.这样自动增长ID也将会从1开始. 清空表的sql如下 truncate table ...
- J.U.C知识点梳理
java.util.concurrent : 提供了并发编程的解决方案 1.CAS 是java.util.concurrent.atomic包的基础 2.AQS是java.util.concurren ...
- 浅谈JavaScript中的正则表达式(适用初学者观看)
浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...
- PAT 乙级 1088
题目 题目链接:PAT 乙级 1088 题解 比较简单的一道题,下面来简单说说思路: 因为甲确定是一个两位数,因此通过简单的暴力循环求解甲的值,又根据题设条件“把甲的能力值的 2 个数字调换位置就是乙 ...