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;
    }

  • 相关阅读:
    WMS、WCS、PLC、AGV
    SAP消息号修改汇总
    SQL 计算累计和 sum() over( partition by order by )
    DDLS报错数据类型冲突:data type conflict in a selection 解决办法
    SAP销售订单需求类型的确定优先级
    SAP替代,出口U904在RGGBS000中未生成
    订单BOM与销售BOM的区别
    在配置和销售凭证 GET_CONFIG_MODE 间通信时内部出错
    ABAP Write
    php的api接口
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632709.html
Copyright © 2011-2022 走看看