zoukankan      html  css  js  c++  java
  • 并查集 [POI2007]洪水pow

     

    问题 E: [POI2007]洪水pow

    时间限制: 5 Sec  内存限制: 128 MB

    题目描述

    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,且可以为零.

    输出

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

    样例输入

    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
     
    

    样例输出

    2

    提示

        其实能够证明,放在城市一定最优。。从最低的地点开始处理,因为抽水机建的越低一定最优。用一个p[]数组记录这个点是不是已经能被抽水了。在遍历的时候,找这个点四周已被标记的点(说白了就是比他低的),合并为自己的父亲,看能否连上。在每搜完一个高度以后,找刚刚遍历的点,看是否有没联通的城市,如果有那他就得建抽水机了。(不能最后判断,不然高地势会把连不上的低地势连上的)
       
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int n,m,cnt,ans;
    struct city
    {
        int h,id;
         friend bool operator <( city a, city b){return a.h<b.h;}
    }a[1000005];
    int f[1000005],vis[10000005],id[1005][1005],v[1000005];
    int p[1000005],t2[4][2]={{-1,0,},{0,-1,},{0,1,},{1,0,},};
    int find(int x)
    {
        if(f[x]!=x)f[x]=find(f[x]);
        return f[x];
    }
    void get(int g)
    {
        int k=a[g].id;int x=(k-1)/m+1,y=(k-1)%m+1;
        for(int i=0;i<4;i++)
        {   
            int x1=x+t2[i][0],y1=y+t2[i][1];
            if(x1>=1&&x1<=n&&y1>=1&&y1<=m)
            {
                int l=id[x1][y1];
                if(vis[l])
                {
                     int fx=find(l);
                     p[k]=(p[k]||p[fx]);
                     f[fx]=find(k);
                }
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
           for(int j=1;j<=m;j++)
           {
                scanf("%d",&a[++cnt].h);
                id[i][j]=cnt;
                if(a[cnt].h>0)v[cnt]=1;
                else a[cnt].h=abs(a[cnt].h);
                //v[i][j]=a[cnt].h;
                a[cnt].id=cnt;
                f[cnt]=cnt;
           }
        sort(a+1,a+cnt+1);
        int last=1;
        for(int i=1;i<=cnt;i++)
        {
            get(i);
            vis[a[i].id]=1;
            if(a[i+1].h!=a[i].h)
            {
                for(int j=last;j<=i;j++)
                {
                    int k=a[j].id;
                    if(v[k]&&!p[find(k)])
                    {
                        ans++;
                        p[find(k)]=1;
                    }           
                }
                last=i+1;
            }
        }
        cout<<ans;
    }

  • 相关阅读:
    HAproxy 1.5 dev14 发布
    IBM/DW 使用 Java 测试网络连通性的几种方法
    Skype 4.1 Linux 发布,支持微软帐号登录
    Dorado 7.1.20 发布,Ajax的Web开发平台
    Aspose.Slides for Java 3.0 发布
    开发版本 Wine 1.5.18 发布
    BitNami Rubystack 开始支持 Ruby 2.0
    XWiki 4.3 正式版发布
    Silverlight实例教程 Out of Browser的Debug和Notifications窗口
    Silverlight实例教程 Out of Browser与Office的互操作
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632709.html
Copyright © 2011-2022 走看看