題梗
琵琶島被分割爲了 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;
}
(二維轉一維,)