[vijos1944]琵琶湖(並查集)

題梗

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章