[POI2007]POW-The Flood(并查集)
[POI2007]POW-The Flood
Description
AKD 市处在一个四面环山的谷地里。最近一场大暴雨引发了洪水,AKD 市全被水淹没了。Blue Mary,AKD 市的市长,召集了他的所有顾问(包括你)参加一
个紧急会议。经过细致的商议之后,会议决定,调集若干巨型抽水机,将它们放
在某些被水淹的区域,而后抽干洪水。
你手头有一张 AKD 市的地图。这张地图是边长为 mn 的矩形,被划分为 mn个 11 的小正方形。对于每个小正方形,地图上已经标注了它的海拔高度以及它是否是 AKD 市的一个组成部分。地图上的所有部分都被水淹没了。并且,由于这张地图描绘的地面周围都被高山所环绕,洪水不可能自动向外排出。显然,我们没有必要抽干那些非 AKD 市的区域。
每个巨型抽水机可以被放在任何一个 11 正方形上。这些巨型抽水机将持续地抽水直到这个正方形区域里的水被彻底抽干为止。当然,由连通器原理,所有能向这个格子溢水的格子要么被抽干,要么水位被降低。每个格子能够向相邻的格子溢水,“相邻的”是指(在同一高度水平面上的射影)有公共边。
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(并查集)的更多相关文章
- 洛谷P3457 [POI2007]POW-The Flood [并查集,模拟]
题目传送门 pow 题意翻译 Description 你手头有一张该市的地图.这张地图是边长为 m∗n 的矩形,被划分为m∗n个1∗1的小正方形.对于每个小正方形,地图上已经标注了它的海拔高度以及它是 ...
- [POI2007]洪水pow 并查集
我们先得出一个结论:水泵要建在城市上.因为如果在非城市上建能把其他一些城市抽干,那么在城市上建也是一个效果(自己画图感性理解一下) 然后我们明白抽水的条件:周围的高度要>=自身的高度,这样会抽完 ...
- 【Luogu3457】POW-The Flood(并查集)
[Luogu3457]POW-The Flood(并查集) 题面 洛谷 题解 我们知道,如果一个点和一个海拔不高于它的点相连 那么连在那个点是更优的,所以考虑按照每个点的海拔排序 既然按照海拔排序,相 ...
- 并查集 - BZOJ 1104 [POI2007]洪水
BZOJ 1104 [POI2007]洪水 描述 AKD 市处在一个四面环山的谷地里.最近一场大暴雨引发了洪水,AKD 市全被水淹没了.Blue Mary,AKD 市的市长,召集了他的所有顾问(包括你 ...
- BZOJ 1098 [POI2007]办公楼biu(反向图bfs+并查集优化)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1098 [题目大意] 现在有一张图,要求将这张图的点划分为尽量多的分组,对于不同分组的两 ...
- poj2236(并查集)
题目链接: http://poj.org/problem?id=2236 题意: 有n台计算机, 已知每台计算机的坐标, 初始时所有计算机都是坏的, 然后修复其中一些计算机, 已修复的计算机距离不超过 ...
- POJ 2236 Wireless Network (并查集)
Wireless Network Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 18066 Accepted: 761 ...
- [POJ 2588]--Snakes(并查集)
题目链接:http://poj.org/problem?id=2588 Snakes Time Limit: 1000MS Memory Limit: 65536K Description B ...
- BZOJ 2303: [Apio2011]方格染色 [并查集 数学!]
题意: $n*m:n,m \le 10^6$的网格,每个$2 \times 2$的方格必须有1个或3个涂成红色,其余涂成蓝色 有一些方格已经有颜色 求方案数 太神了!!!花我三节课 首先想了一下只有两 ...
- Codeforces445B(SummerTrainingDay06-N 并查集)
B. DZY Loves Chemistry time limit per test:1 second memory limit per test:256 megabytes input:standa ...
随机推荐
- .NET COM+级别的事务Transaction实现
参考: https://docs.microsoft.com/zh-cn/dotnet/api/system.enterpriseservices.contextutil?view=netframew ...
- 数据库-SqlServer 行转列,列转行
两篇行转列,列转行的实例文章: 第1篇:https://www.cnblogs.com/cpcpc/archive/2013/04/08/3009021.html 第2篇:https://mp.wei ...
- PhantomJs 与 Casperjs
利用PhantomJS做网页截图经济适用,但其API较少,做其他功能就比较吃力了. CasperJs是对phantomjs的一次封装.即phantomjs是原生的,而casperjs是封装在以phan ...
- ThreadPoolExecutor 源码分析
ThreadPoolExecutor 线程池核心实现类 线程池的生命周期 RUNNING: 接受新任务,同时处理工作队列中的任务 SHUTDOWN: 不接受新任务,但是能处理工作队列中的任务 STOP ...
- 用Vue来实现音乐播放器(十六):滚动列表的实现
滚动列表是一个基础组件 他是基于scroll组件实现的 在base文件夹下面创建一个list-view文件夹 里面有list-view.vue组件 <template> < ...
- Python高效率遍历文件夹寻找重复文件
前言 为什么要写这篇文章呢...主要还是业务中有个需求,遍历一个将近200w数据的文件夹,大部分还都是视频文件那种,但是这玩意用的次数还不多,做文件夹index也不是很ok,所以写了一个脚本来处理这个 ...
- git_04_回退到上个版本
前言 使用git版本控制的过程中,多人操作同一个项目时,有时经常会遇到代码冲突报错,一时又无法解决的问题,为了不影响他人正常使用这时便需要回滚代码至原来的版本.如何回滚代码至原来版,可参考以下步骤. ...
- Vue入门---安装及常用指令介绍
1.安装 BootCDN----官网https://www.bootcdn.cn/ <script src="https://cdn.bootcss.com/vue/2.6.10/vu ...
- sqlMap.xml配置文件中迭代一个集合的方式
比如:根据班级号查询学生的信息,参数是list 1.foreach的用法:[写法一] <select id="getStudentListByClassId" resultM ...
- 2019南京网络赛E:K Sum
Description: 定义函数 \[ f _n (k) = \sum _{l _1 = 1} ^n \sum _{l _2 = 1} ^n \cdots \sum _{l _k = 1} ^n \ ...