并查集 - 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...代表程序中出现的变量 ...
随机推荐
- They say Rome wasn't built in a day, and yet what a difference a day makes.
They say Rome wasn't built in a day, and yet what a difference a day makes.有人说罗马不是一天建成的,但一天却能改变很多事.
- session会话
jsp会话篇session: package com.log; import java.io.IOException; import java.util.ArrayList; import java. ...
- Android笔记--LayoutInflator源码和使用分析
LayoutInflator源码分析 获取LayoutInflator对象 获取LayoutInflator的方式有两种: 使用LayoutInflator.from(Context context) ...
- ios中frame设置宽高计算的Demo
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ int totalHeightOfScrollView = scrollView.con ...
- SQL Server 2017的Linked Server配置触发的bug“Exception Code = c0000005 EXCEPTION_ACCESS_VIOLATION”
SQL Server 2017的Linked Server配置触发的bug"Exception Code = c0000005 EXCEPTION_ACCESS_VIOLATION&q ...
- BZOJ 1137: [POI2009]Wsp 岛屿 半平面交
1137: [POI2009]Wsp 岛屿 Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 165 Solved: ...
- Windows环境下使用Apache+mod
1.安装Python和Apache. 2.安装mod_wsgi后获得wsgi.so,并将wsgi.so放到Apache的modules文件夹下. 3.安装webpy. 4.打开httpd.conf(在 ...
- Happy Equation
Source: The 10th Shandong Provincial Collegiate Programming Contest 题解: 因为2^p为偶数,所以a,x的奇偶性相同 1.当a为奇数 ...
- LEETCODE60——第K个排列
class Solution { public: string getPermutation(int n, int k) { '); vector<bool> flag(n, false) ...
- NOIP2016——大家一起实现の物语
由于最近硬盘挂了,换了个固态硬盘,比赛结束后四天一直在装Linux,所以最近一直没怎么更新 看起来挺漂亮的 比赛前一个月申请停了一个月晚自习,在我们这座城市里能做到这种事情已经可以被称为奇迹了,并且在 ...