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\n",ans);
60     return 0;
61 }
View Code

 

posted @ 2018-05-22 19:35  Blue233333  阅读(184)  评论(0编辑  收藏  举报