• BZOJ1104: [POI2007]洪水pow


    $n leq 1000,m leq 1000$,$n*m$的地图,每个格一个海拔,现在整个图都是水,问要多少个地方装抽水机能使所有指定位置被抽干(符合连通器原理)。

    从小到大枚举每个指定格,然后有贡献的就是比当前指定格小的所有格,把他们用并查集搞起来。如果这样也不能使当前格被一个装了抽水机的并查集覆盖,就在自己并查集里装一个。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 //#include<set>
     5 #include<algorithm>
     6 //#include<math.h>
     7 //#include<iostream>
     8 //#include<time.h>
     9 using namespace std;
    10 
    11 #define LL long long
    12 int qread()
    13 {
    14     char c; int s=0,t=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (t=-1);
    15     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*t;
    16 }
    17 
    18 //Pay attention to read!
    19 
    20 int n,m;
    21 #define maxn 1011
    22 int a[maxn][maxn],id[maxn][maxn],qx[maxn*maxn],qy[maxn*maxn],head,tail,ufs[maxn*maxn];
    23 bool vv[maxn][maxn],vis[maxn*maxn];
    24 int find(int x) {return x==ufs[x]?x:(ufs[x]=find(ufs[x]));}
    25 void Union(int x,int y) {x=find(x),y=find(y); if (x==y) return; ufs[x]=y; vis[y]|=vis[x];}
    26 
    27 int ans=0;
    28 const int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
    29 int Abs(int x) {return x>0?x:-x;}
    30 
    31 struct Node{int x,y,v; bool operator < (const Node &b) const {return v<b.v;}}pp[maxn*maxn],qq[maxn*maxn];
    32 int lq;
    33 
    34 int main()
    35 {
    36     n=qread(); m=qread();
    37     for (int i=1;i<=n;i++) for (int j=1;j<=m;j++)
    38     {
    39         a[i][j]=qread(),id[i][j]=(i-1)*m+j,pp[id[i][j]]=(Node){i,j,Abs(a[i][j])};
    40         if (a[i][j]>0) qq[++lq]=(Node){i,j,a[i][j]};
    41     }
    42     sort(pp+1,pp+1+n*m);
    43     sort(qq+1,qq+1+lq);
    44     for (int i=1;i<=n*m;i++) ufs[i]=i;
    45     for (int i=1,j=1;i<=lq;i++)
    46     {
    47         for (;j<=n*m && pp[j].v<=qq[i].v;j++)
    48         {
    49             int nx=pp[j].x,ny=pp[j].y;
    50             for (int k=0;k<4;k++)
    51             {
    52                 int x=nx+dx[k],y=ny+dy[k];
    53                 if (x<1 || x>n || y<1 || y>m) continue;
    54                 if (Abs(a[x][y])<=Abs(a[nx][ny])) Union(id[x][y],id[nx][ny]);
    55             }
    56         }
    57         if (!vis[find(id[qq[i].x][qq[i].y])]) vis[ufs[id[qq[i].x][qq[i].y]]]=1,ans++;
    58     }
    59     printf("%d
    ",ans);
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    mySQL优化方案
    java之自动过滤提交文本中的html代码script代码
    java小技术之生成二维码
    微信扫码支付功能详细教程————Java
    java实现发送邮件服务器,SMTP协议发送邮件
    『重构--改善既有代码的设计』读书笔记----序
    Linux导航神器-----autojump
    绘图时,根据size()和自定义rect编程的区别
    Qt中如何在QCursor移动的时候不触发moveEvent
    Qt远程机开发时光标注意问题
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9073683.html
Copyright © 2020-2023  润新知