zoukankan      html  css  js  c++  java
  • 2017.8.13 [POI2007]洪水pow 并查集 (题意比较难理解)

    题目描述

    AKD市处在一个四面环山的谷地里。最近一场大暴雨引发了洪水,AKD市全被水淹没了。Blue Mary,AKD市的市
    长,召集了他的所有顾问(包括你)参加一个紧急会议。经过细致的商议之后,会议决定,调集若干巨型抽水机,
    将它们放在某些被水淹的区域,而后抽干洪水。你手头有一张AKD市的地图。这张地图是边长为m*n的矩形,被划分
    为m*n个1*1的小正方形。对于每个小正方形,地图上已经标注了它的海拔高度以及它是否是AKD市的一个组成部分
    。地图上的所有部分都被水淹没了。并且,由于这张地图描绘的地面周围都被高山所环绕,洪水不可能自动向外排
    出。显然,我们没有必要抽干那些非AKD市的区域。每个巨型抽水机可以被放在任何一个1*1正方形上。这些巨型抽
    水机将持续地抽水直到这个正方形区域里的水被彻底抽干为止。当然,由连通器原理,所有能向这个格子溢水的格
    子要么被抽干,要么水位被降低。每个格子能够向相邻的格子溢水,“相邻的”是指(在同一高度水平面上的射影
    )有公共边。

    输入

    第一行是两个数m,n(1<=m,n<=1000). 以下m行,每行n个数,其绝对值表示相应格子的海拔高度;若该数为正
    ,表示他是AKD市的一个区域;否则就不是。请大家注意:所有格子的海拔高度其绝对值不超过1000,且可以为零.

    输出

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

    solution

    题意理解

    一开始洪水把图全淹了
    洪水并不是只能向四周流,直到四周的高度,(题中的降到水平线即是这个意思)
    负的海拔不是真的负,只是为了标记一下非城市.....
    题中是一个很真实的山地....

    我们考虑每一个城市的水被排完,当且仅当此城市有抽水机 OR 与它有有一条水能流过去的路径的点装了抽水机

    所以可以在某几个点放抽水机,而所有城市节点都被抽光

    而一个城市的水被抽光,一定是high<=它的点放了抽水机

    所以把每一个点的海拔从小到大排序

    从小到大遍历城市节点的同时

    遍历所有节点,把high<=当前城市节点的点 与其周围的比它低的点 连起来(这样可以保证某一个点被围起来就不会对其他点做出贡献)

    用并查集来维护

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #define mem(a,b) memset(a,b,sizeof(a))
     6 using namespace std;
     7 const int N=1006;
     8 
     9 struct son
    10 {
    11     int x,y,val;
    12     friend bool operator < (son a,son b)
    13     {
    14         return a.val<b.val;
    15     }
    16 };
    17 son ji[N*N];
    18 int n,m,ans;
    19 int h[N][N],ha[N][N];
    20 
    21 int fa[N*N],flag[N*N];
    22 int fin(int x)
    23 {
    24     if(fa[x]==-1)
    25       return x;
    26     return fa[x]=fin(fa[x]);
    27 }
    28 void match(int u,int v)
    29 {
    30     int x=fin(u),y=fin(v);
    31     if(x!=y)
    32     {
    33         fa[x]=y;
    34         flag[y]|=flag[x];
    35     }
    36 }
    37 
    38 void out11()
    39 {
    40     printf("
    ");
    41     for(int i=1;i<=n;++i)
    42     {
    43         for(int j=1;j<=m;++j)
    44           printf("%d ",ha[i][j]);
    45         printf("
    ");
    46     }
    47     printf("
    ");
    48 }
    49 
    50 int main(){
    51     
    52     //freopen("1.txt","r",stdin);
    53     
    54     mem(fa,-1);
    55     
    56     scanf("%d%d",&n,&m);
    57     for(int i=1;i<=n;++i)
    58       for(int j=1;j<=m;++j)
    59       {
    60             scanf("%d",&h[i][j]);
    61             ha[i][j]=(i-1)*m+j;
    62             ji[ha[i][j]]=(son){i,j,abs(h[i][j])};
    63         }
    64     sort(ji+1,ji+1+n*m);
    65     //out11();
    66     son temp;
    67     int now=1;
    68     for(int sss=n*m,i=1;i<=sss;++i)
    69     {
    70         if(h[ji[i].x][ji[i].y]<=0)
    71           continue;
    72         while(ji[now].val<=ji[i].val&&now<=sss)//连四周正好可以防止高地把它围起来
    73         {
    74             temp=ji[now];
    75             if(temp.x>1&&abs(h[temp.x-1][temp.y])<=temp.val)
    76                 match(ha[temp.x][temp.y],ha[temp.x-1][temp.y]);
    77             if(temp.x<n&&abs(h[temp.x+1][temp.y])<=temp.val)
    78                 match(ha[temp.x][temp.y],ha[temp.x+1][temp.y]);
    79             if(temp.y>1&&abs(h[temp.x][temp.y-1])<=temp.val)
    80                 match(ha[temp.x][temp.y],ha[temp.x][temp.y-1]);
    81             if(temp.y<m&&abs(h[temp.x][temp.y+1])<=temp.val)
    82                 match(ha[temp.x][temp.y],ha[temp.x][temp.y+1]);
    83             ++now;
    84         }
    85         temp=ji[i];
    86         if(!flag[fin(ha[temp.x][temp.y])])
    87         {
    88             ++ans;
    89             //printf("x=%d y=%d
    ",temp.x,temp.y);
    90             flag[fin(ha[temp.x][temp.y])]=1;
    91         }
    92     }
    93     
    94     cout<<ans;
    95     //while(1);
    96     return 0;
    97 }
    code
  • 相关阅读:
    Android--Android studio --布局管理
    Android--Android studio --Activity
    Android--Android studio --app运行
    Android--Android studio 工程目录分析
    Java--Niit-ch2--Location本地化问题
    C--循环实现和递归实现的比较
    C--函数调用
    【未完待续】Java蓝桥杯--算法训练 数学知识的运用
    【未完待续】Java蓝桥杯--算法训练(1)典型问题的递归框架
    NIIT2--JAVA活动(一)制作内部类 正则内部类
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7354044.html
Copyright © 2011-2022 走看看