[POI2007]POW-The Flood

Description

AKD 市处在一个四面环山的谷地里。最近一场大暴雨引发了洪水,AKD 市全被水淹没了。Blue Mary,AKD 市的市长,召集了他的所有顾问(包括你)参加一

个紧急会议。经过细致的商议之后,会议决定,调集若干巨型抽水机,将它们放

在某些被水淹的区域,而后抽干洪水。

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

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

Input

第一行是两个数 \(m,n(1<=m,n<=1000)\).

以下 m 行,每行 n 个数,其绝对值表示相应格子的海拔高度;若该数为正,表

示他是 AKD 市的一个区域;否则就不是。

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

Output

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

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

考试的时候推样例都推了很久,有巨佬居然瞎xx乱搞拿了40???Orz

一个很重要的结论:我们要在所有“山谷”放抽水机。所以我们把每个点的海拔从小到大排序 ,对于每一个点,把它和周围比它低的点并入一个集合,因为比它低的点水排走了,它的水也就排走了,所以这个集合里最小的点放上了抽水机,就一定能保证这个集合的水全部被排走。

所以对于每一组海拔相同的点,如果它加入的集合中有城市但是没有放抽水机,就需要放抽水机。显然再往后海拔变高不可能在把它排空。

还有一个细节:将同一高度的格子合并完后再放置抽水机。显然两个格子3 4 3是可以在一个集合的,所以我们不要边合并边判断要不要放抽水机。

sb错误:排序后没有记录原位置,导致处理出错

#include<bits/stdc++.h>
using namespace std;
int read()
{
int x=0,w=1;char ch=getchar();
while(ch>'9'||ch<'0') {if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*w;
}
int m,n,cnt,last,ans;
bool fang[2000010];
int a[1010][1010],fa[2000010];
struct node{
int x,y,v,cnt;
}f[2000010];
bool cmp(node p,node q){return p.v<q.v;}
int gfa(int x){if(x==fa[x])return x;return fa[x]=gfa(fa[x]);}
void change(int k)
{
for(int i=last;i<=k;i++)
{
int ff=gfa(f[i].cnt);
if(!fang[ff]&&a[f[i].x][f[i].y]>0) ans++,fang[ff]=1;
}
}
void hebing(int x,int y)
{
int xx=gfa(x),yy=gfa(y);
if(xx==yy) return;
fa[yy]=xx;fang[xx]|=fang[yy];
}
int main()
{
n=read();m=read();memset(a,127,sizeof(a));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
a[i][j]=read();
cnt++;f[cnt].x=i;f[cnt].y=j;f[cnt].v=abs(a[i][j]);fa[cnt]=cnt;f[cnt].cnt=cnt;
}
}
sort(f+1,f+1+cnt,cmp);last=1;f[0].v=0x7fffffff;
for(int i=1;i<=cnt;i++)
{
if(f[i].v!=f[i-1].v&&i!=1) {change(i-1);last=i;}
int x=f[i].x,y=f[i].y;
if(f[i].v>=abs(a[x-1][y])) hebing(f[i].cnt,(x-2)*m+y);
if(f[i].v>=abs(a[x+1][y])) hebing(f[i].cnt,x*m+y);
if(f[i].v>=abs(a[x][y-1])) hebing(f[i].cnt,(x-1)*m+y-1);
if(f[i].v>=abs(a[x][y+1])) hebing(f[i].cnt,(x-1)*m+y+1);
}change(f[cnt].cnt);
cout<<ans;
}

[POI2007]POW-The Flood(并查集)的更多相关文章

  1. 洛谷P3457 [POI2007]POW-The Flood [并查集,模拟]

    题目传送门 pow 题意翻译 Description 你手头有一张该市的地图.这张地图是边长为 m∗n 的矩形,被划分为m∗n个1∗1的小正方形.对于每个小正方形,地图上已经标注了它的海拔高度以及它是 ...

  2. [POI2007]洪水pow 并查集

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

  3. 【Luogu3457】POW-The Flood(并查集)

    [Luogu3457]POW-The Flood(并查集) 题面 洛谷 题解 我们知道,如果一个点和一个海拔不高于它的点相连 那么连在那个点是更优的,所以考虑按照每个点的海拔排序 既然按照海拔排序,相 ...

  4. 并查集 - BZOJ 1104 [POI2007]洪水

    BZOJ 1104 [POI2007]洪水 描述 AKD 市处在一个四面环山的谷地里.最近一场大暴雨引发了洪水,AKD 市全被水淹没了.Blue Mary,AKD 市的市长,召集了他的所有顾问(包括你 ...

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

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

  6. poj2236(并查集)

    题目链接: http://poj.org/problem?id=2236 题意: 有n台计算机, 已知每台计算机的坐标, 初始时所有计算机都是坏的, 然后修复其中一些计算机, 已修复的计算机距离不超过 ...

  7. POJ 2236 Wireless Network (并查集)

    Wireless Network Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 18066   Accepted: 761 ...

  8. [POJ 2588]--Snakes(并查集)

    题目链接:http://poj.org/problem?id=2588 Snakes Time Limit: 1000MS   Memory Limit: 65536K   Description B ...

  9. BZOJ 2303: [Apio2011]方格染色 [并查集 数学!]

    题意: $n*m:n,m \le 10^6$的网格,每个$2 \times 2$的方格必须有1个或3个涂成红色,其余涂成蓝色 有一些方格已经有颜色 求方案数 太神了!!!花我三节课 首先想了一下只有两 ...

  10. Codeforces445B(SummerTrainingDay06-N 并查集)

    B. DZY Loves Chemistry time limit per test:1 second memory limit per test:256 megabytes input:standa ...

随机推荐

  1. Qt android 配置

    http://www.cnblogs.com/ztzheng/p/3703716.html

  2. Redis 序列化方式StringRedisSerializer、FastJsonRedisSerializer和KryoRedisSerializer

    当我们的数据存储到Redis的时候,我们的键(key)和值(value)都是通过Spring提供的Serializer序列化到数据库的.RedisTemplate默认使用的是JdkSerializat ...

  3. ARC093 F - Dark Horse

    https://atcoder.jp/contests/arc093/tasks/arc093_d 题解 先钦定\(1\)号站在第一个位置上,那么他第一轮要和\((2)\)打,第二轮要和\((3,4) ...

  4. C/C++头文件的编写

    在C语言的学习过程中,我们一般把所有的代码写在一个文件中.随着自身水平的提高,我们发现代码越写越长,代码行数越来越多,把一个工程的所有代码写在一个文件中让人看起开非常吃力.于是我们开始想把代码中的函数 ...

  5. Oracle传输数据到Sqlserver

    通过Sqlserver的SSIS工具实现数据传输

  6. [CSP-S模拟测试]:玩具(概率DP)

    题目描述 这个故事发生在很久以前,在$IcePrincess\text{_}1968$和$IcePrince\text{_}1968$都还在上幼儿园的时候. $IcePrince\text{_}196 ...

  7. 正则表达式小结,数据预处理中常用的shell命令

    数据预处理中,这部分命令非常有用. 不需要编写代码,直接通过shell脚本通常就能修改文件格式.有时候sed和awk联合几乎能实现所有功能. 管道命令 | 重定向命令>,2>,>&g ...

  8. 后端PHP框架laravel学习踩的各种坑

    安装完laravel的ventor目录后出现“Whoops, looks like something went wrong.”这样的错误信息 打开config/app.php,打开debug为tru ...

  9. rime 同文输入法 安卓系统

    下载安装APP 从google play下载同文输入法 默认安装完只有3个输入法, 没有五笔和拼音 [官网][https://rime.im/download/] 获取五笔拼音方案 然后找到 /sdc ...

  10. UI自动化之读取浏览器配置

    以火狐浏览器为例 目录 1.找到配置项 2.读取配置 1.找到配置项 打开Firefox点右上角设置>?(帮助)>故障排除信息>显示文件夹,复制文件管理器地址栏 2.读取配置 用Fi ...