题梗
琵琶岛被分割为了 n x m 的格子图。每一块格子区域都有着确定的高度。不幸的是,琵琶湖的水位最近开始上涨了,第 i 年湖面的高度将上涨至 i 米。另外一方面,琵琶岛是由松软的土质形成的,且琵琶湖的湖水可以自由渗入到其中。也就是说,如果有一块格子区域的高度不超过当前的水位,则将被淹没。相连的未被淹没的格子(有着公共边的格子区域)将组成一块未被淹没的区域。
求对于指定的某一年来说,琵琶岛被分割为了多少块未被淹没的区域。(AH2015T4)
#include<iostream>
#include<algorithm>
using namespace std;
const int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
const int maxn=1000100;
struct node{
int x,y,h;
}a[maxn];
int k,q[maxn];
int n,m,fa[maxn],sum[maxn];
int book[1010][1010];
int find(int x){
if (fa[x]!=x) fa[x]=find(fa[x]);
return fa[x];
}
int pd(int x,int y){
x=find(x);
y=find(y);
return x==y;
}
void merge(int x,int y){
x=find(x);
y=find(y);
fa[x]=y;
}
int cmp(node a,node b){
return a.h>b.h;
}
int main(){
cin>>n>>m;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++){
int t=(i-1)*m+j;
a[t].x=i;
a[t].y=j;
fa[t]=t;
cin>>a[t].h;
}
sort(a+1,a+n*m+1,cmp);
cin>>k;
for (int i=1;i<=k;i++)
cin>>q[i];
int now=1,ans=0;
for (int i=k;i>=1;i--){
while (now<=n*m&&a[now].h>q[i]){
ans++;
int nowx=a[now].x,nowy=a[now].y;
book[nowx][nowy]=1;
for (int j=0;j<4;j++){
int tx=nowx+dir[j][0];
int ty=nowy+dir[j][1];
if (tx<1||tx>n||ty<1||ty>m||!book[tx][ty]) continue;
int id1=(tx-1)*m+ty;
int id2=(nowx-1)*m+nowy;
if (!pd(id1,id2)){
merge(id1,id2);
ans--;
}
}
now++;
}
sum[i]=ans;
}
for (int i=1;i<=k;i++) cout<<sum[i]<<" ";
return 0;
}
(二维转一维,)