A.Islands

这种联通块的问题一看就知道是并查集的思想。

做法:从高水位到低水位依序进行操作,这样每次都有新的块浮出水面,可以在前面的基础上进行合并集合的操作。
给每个位置分配一个数字,方便合并集合。同时将这些数字也排一个序,降低枚举的复杂度。合并集合时向四周查询浮出水面但是没有合并到同一集合的点进行合并。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define N 1007

struct node
{
    int x,y,h;
}p[N*N];

int a[N*N],sh[100005],cnt[100005],fa[N*N];
int n,m;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};

int cmp(node ka,node kb)
{
    return ka.h < kb.h;
}

int findset(int x)
{
    if(x != fa[x])
        fa[x] = findset(fa[x]);
    return fa[x];
}

inline int ok(int x,int y)
{
    if(x < n && x >= 0 && y < m && y >= 0)
        return 1;
    return 0;
}

int main()
{
    int t,i,j,k,q,ind,pos;
    scanf("%d",&t);
    while(t--)
    {
        memset(cnt,0,sizeof(cnt));
        scanf("%d%d",&n,&m);
        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                pos = i*m+j;
                fa[pos] = pos;
                scanf("%d",&a[pos]);
                p[pos].x = i,p[pos].y = j,p[pos].h = a[pos];
            }
        }
        scanf("%d",&q);
        for(i=0;i<q;i++)
            scanf("%d",&sh[i]);
        sort(p,p+n*m,cmp);
        i = n*m-1;
        for(j=q-1;j>=0;j--)
        {
            cnt[j] = cnt[j+1];
            while(sh[j] < p[i].h)  //浮出水面
            {
                cnt[j]++;
                ind = p[i].x*m+p[i].y;
                int fx = findset(ind);
                for(k=0;k<4;k++)
                {
                    int tx = p[i].x + dx[k];
                    int ty = p[i].y + dy[k];
                    if(!ok(tx,ty))
                        continue;
                    int newind = tx*m+ty;
                    int fy = findset(newind);
                    if(fx != fy && sh[j] < a[newind]) //浮出水面且没有合并
                    {
                        fa[fy] = fx;   //不能使fa[fx] = fy.因为本次fx不会再findset.
                        cnt[j]--;
                    }
                }
                i--;
            }
        }
        for(i=0;i<q;i++)
            printf("%d ",cnt[i]);
        printf("\n");
    }
    return 0;
}
View Code

相关文章:

  • 2022-02-11
  • 2021-07-06
  • 2022-12-23
  • 2021-08-26
  • 2021-11-06
  • 2022-01-09
  • 2022-02-03
  • 2022-02-12
猜你喜欢
  • 2021-11-22
  • 2021-07-07
  • 2021-05-28
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案