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,且可以为零.
只有一行,包含一个整数,表示至少需要放置的巨型抽水机数目。
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<queue>
6 using namespace std;
7 #define inf 0x3f3f3f3f
8 #define maxn 1005
9 int read() {
10 int s=0,f=1;
11 char ch=getchar();
12 while(ch>‘9‘||ch<‘0‘) {
13 if(ch==‘-‘) {
14 f=-1;
15 }
16 ch=getchar();
17 }
18 while(ch>=‘0‘&&ch<=‘9‘) {
19 s=(s<<1)+(s<<3)+(ch^48);
20 ch=getchar();
21 }
22 return s*f;
23 }
24 int n,m,h[maxn][maxn],fa[maxn*maxn],cnt,ans,mv[4][2]= {1,0,-1,0,0,1,0,-1},empty[maxn*maxn];
25 int num[maxn][maxn],tot;
26 struct oo {
27 int x,y,hei;
28 friend bool operator < (oo a,oo b) {
29 return a.hei<b.hei;
30 }
31 } s[maxn*maxn],l[maxn*maxn];
32 inline int find(int x) {
33 return fa[x]==x?x:fa[x]=find(fa[x]);
34 }
35 void init() {
36 for(int i=0; i<=n+1; ++i)
37 h[i][0]=h[i][m+1]=inf;
38 for(int i=0; i<=m+1; ++i)
39 h[0][i]=h[n+1][i]=inf;
40 for(int i=1; i<=n*m; ++i) {
41 fa[i]=i;
42 }
43 for(int i=1; i<=n; ++i) {
44 for(int j=1; j<=m; ++j) {
45 num[i][j]=++tot;
46 }
47 }
48 }
49 int main() {
50 n=read(),m=read();
51 init();
52 memset(empty,0,sizeof(empty));
53 for(int i=1; i<=n; ++i) {
54 for(int j=1; j<=m; j++) {
55 h[i][j]=read();
56 if(h[i][j]>0) {
57 s[++cnt].x=i,s[cnt].y=j,s[cnt].hei=h[i][j];
58 } else {
59 h[i][j]=-h[i][j];
60 }
61 l[num[i][j]].x=i,l[num[i][j]].y=j,l[num[i][j]].hei=h[i][j];
62 }
63 }
64 sort(l+1,l+m*n+1);
65 sort(s+1,s+cnt+1);
66 ans=0;
67 for(int i=1,k=1; i<=cnt; ++i) {
68 for(; k<=m*n&&l[k].hei<=s[i].hei; ++k) {
69 int x=l[k].x,y=l[k].y;
70 for(int j=0; j<=3; j++) {
71 int xx=x+mv[j][0],yy=y+mv[j][1];
72 if(h[xx][yy]<=h[x][y]) {
73 empty[find(num[x][y])]|=empty[find(num[xx][yy])];
74 fa[find(num[xx][yy])]=find(num[x][y]);
75 }
76 }
77 }
78 if(!empty[find((s[i].x-1)*m+s[i].y)]) {
79 ++ans;
80 empty[find((s[i].x-1)*m+s[i].y)]=1;
81 }
82 }
83 printf("%d\n",ans);
84 return 0;
85 }