我们先得出一个结论:水泵要建在城市上。因为如果在非城市上建能把其他一些城市抽干,那么在城市上建也是一个效果(自己画图感性理解一下)

然后我们明白抽水的条件:周围的高度要>=自身的高度,这样会抽完它。如果低的话,会降低旁边位置的水位(这很重要)

然后我们枚举每一个城市,看它用不用建造。这样在每一个城市,枚举所有位置,看这个位置能不能被四周的抽干,这样用并查集维护,能抽干的都是一个祖先

这样枚举完一遍后,看这个城市所连的并查集有没有被抽干,如果没有,就在那里建造即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define pos(i,a,b) for(int i=(a);i<=(b);i++)
#define pos2(i,a,b) for(int i=(a);i>=(b);i--)
#define LL long long
#define N 1010
using namespace std;
int map[N][N],n,m,cnt[N][N],ji,vis[N*N];
int fa[N*N],jicity,ans;
struct haha{
    int w,x,y;
}cun[N*N],city[N*N];
bool cmp(const haha &a,const haha &b){
     return a.w<b.w;
}
int find(int x){
    if(fa[x]!=x) fa[x]=find(fa[x]);
    return fa[x];
}
int main(){
    memset(map,0x3f,sizeof(map));
    scanf("%d%d",&n,&m);
    pos(i,1,n)
        pos(j,1,m){
            scanf("%d",&map[i][j]);
            if(map[i][j]>0){
                city[++jicity].w=map[i][j];
                city[jicity].x=i;city[jicity].y=j;
            }
            else map[i][j]=-map[i][j];
            cnt[i][j]=++ji;
            cun[ji].w=map[i][j];
            cun[ji].x=i,cun[ji].y=j;
        }
    sort(cun+1,cun+ji+1,cmp);sort(city+1,city+jicity+1,cmp);
    pos(i,1,ji) fa[i]=i;
    int j=1;
    pos(i,1,jicity){
        int cw=city[i].w,cx=city[i].x,cy=city[i].y;
        for(;j<=ji;j++){
            int w=cun[j].w,x=cun[j].x,y=cun[j].y;
            if(cw<w) break;
            if(map[x][y]>=map[x+1][y]){
                vis[find(cnt[x][y])]|=vis[find(cnt[x+1][y])];
                fa[find(cnt[x+1][y])]=find(cnt[x][y]);
            }
            if(map[x][y]>=map[x][y+1]){
                vis[find(cnt[x][y])]|=vis[find(cnt[x][y+1])];
                fa[find(cnt[x][y+1])]=find(cnt[x][y]);
            }
            if(map[x][y]>=map[x-1][y]){
                vis[find(cnt[x][y])]|=vis[find(cnt[x-1][y])];
                fa[find(cnt[x-1][y])]=find(cnt[x][y]);
            }
            if(map[x][y]>=map[x][y-1]){
                vis[find(cnt[x][y])]|=vis[find(cnt[x][y-1])];
                fa[find(cnt[x][y-1])]=find(cnt[x][y]);
            }
        }
        if(!vis[find(cnt[cx][cy])]){
            ans++;vis[find(cnt[cx][cy])]=1;
        }
    }
    cout<<ans;
    return 0;
}

  

[POI2007]洪水pow 并查集的更多相关文章

  1. [POI2007]洪水pow 题解

    [POI2007]洪水pow 时间限制: 5 Sec  内存限制: 128 MB 题目描述 AKD市处在一个四面环山的谷地里.最近一场大暴雨引发了洪水,AKD市全被水淹没了.Blue Mary,AKD ...

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

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

  3. bzoj1104: [POI2007]洪水pow

    #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #i ...

  4. [POI2007]洪水pow

    Description AKD市处在一个四面环山的谷地里.最近一场大暴雨引发了洪水,AKD市全被水淹没了.Blue Mary,AKD市的市长,召集了他的所有顾问(包括你)参加一个紧急会议.经过细致的商 ...

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

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

  6. [POI2007]洪水pow bfs

    发现:只在所有自己的城市建水泵一定是最优解. 所以对自己的城市按高度排序,该城市不用建的前提是从他出发经过一条高度都小于等于他的路径能到达一个已经修建水泵的 sort+bfs...... #inclu ...

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

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

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

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

  9. poj2236(并查集)

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

随机推荐

  1. 通过ant-jmeter读取jtl文件拆分数据并insert DB

    前言:之前详解过通过jmeter生成的csv文件,解析csv存入DB,这个有弊端 第一:需独立创建一个job 第二:需按照一定规范输出 因此,放弃解析csv方式,直接解析自动化生成的原始jtl文件并集 ...

  2. jQuery怎样判断按钮是否被选中

    方法一: if ($("#checkbox-id")get(0).checked) {     // do something } 方法二: if($('#checkbox-id' ...

  3. SQL显示某月全部日期明细以及SQL日期格式

    SQL显示某月全部日期明细<存储过程> 方法一: declare @date datetime declare @end datetime ,getdate()) ,@date) crea ...

  4. C# selecd,new,virtual,abstract与override

    本文大部分内容摘自  <.NET开发专家·亮剑.NET : .NET深入体验与实战精要> 博主只是搬运工,不喜勿喷. 关于虚方法,抽象类这一部分一直不是太清楚,目前的工作中也接触不到这些. ...

  5. Java分形

    目前笔者接触过的分形主要有一下几种: 1.类似Clifford的分形.这种分形的特点是:分形的初始坐标为(0,0),通过初始坐标经过大量的迭代,得到一系列的点,根据得到的点来绘制分形曲线.这类分形的参 ...

  6. Eclipse工程有乱码

    处理:把整个工程的“Text file encoding”属性设为GBK,就不会有乱码了.设置方法:在eclipse中右击工程,点击弹出框最下面的“Properties”,然后在弹出的窗口左侧点击“R ...

  7. eclipse 修改中英文显示

    1.关闭eclipse 2.右键->选择属性--->打开文件位置 3.找到“eclipse.ini”文件,用EditPlus打开 4.在里面加 “-Duser.language=en”,即 ...

  8. promise异步编程的原理

    一.起源 JavaScript中的异步由来已久,不论是定时函数,事件处理函数还是ajax异步加载都是异步编程的一种形式,我们现在以nodejs中异步读取文件为例来编写一个传统意义的异步函数: var ...

  9. FreeRTOS——内存管理

    1. 标准malloc() 和 free() 库函数的缺陷: 1)在小型的嵌入式系统中,可能不可用. 2)具体实现相对较大,占用较多宝贵的代码空间. 3)通常不具备线程安全性. 4)具有不确定性,每次 ...

  10. JMeter 之Synchronizing Timer运行原理

    JMeter测试并发场景,是通过设置Synchronizing Timer(同步定时器),熟悉LoadRunner性能测试的话,就知道里面有个概念:集合点. Synchronizing Timer则可 ...