zoukankan      html  css  js  c++  java
  • UVA1665 Islands (并查集)

    补题,逆序考虑每个询问的时间,这样每次就变成出现新岛屿,然后用并查集合并统计。fa = -1表示没出现。

    以前写过,但是几乎忘了,而且以前写得好丑的,虽然常数比较小,现在重新写练练手。每个单词后面都要加空格不然PE

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1005;
    const int maxq = 1e5+1;
    
    int q[maxq];
    int pa[maxn*maxn];
    
    int Find(int x){ return x==pa[x]?x:pa[x]=Find(pa[x]); }
    
    int h[maxn][maxn];
    
    struct Node
    {
        int x,y,val;
    }nd[maxn*maxn];
    
    
    bool operator < (const Node &x,const Node &y) { return  x.val < y.val; }
    
    int dx[] = {0,0,-1,1};
    int dy[] = {-1,1,0,0};
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int Z; scanf("%d",&Z);
        while(Z--){
            int m,n; scanf("%d%d",&m,&n);
            for(int i = 0; i < m; i++){
                for(int j = 0; j < n; j++){
                    scanf("%d",h[i]+j);
                    int t = i*n+j;
                    nd[t].x = i; nd[t].y = j;
                    nd[t].val = h[i][j];
                }
            }
    
            sort(nd,nd+m*n);
            memset(pa,-1,sizeof(int)*(m*n));
            int Ts; scanf("%d",&Ts);
            for(int i = 0; i < Ts; i++){
                scanf("%d",q+i);
            }
    
            int k = m*n-1;
            int ans = 0;
            for(int i = Ts-1; i >= 0; i--){
                if(q[i]<nd[k].val){
                    while(k>=0&&q[i]<nd[k].val){
                        int id = nd[k].x*n+nd[k].y;
                        if(!~pa[id]) ans++,pa[id] = id;
                        for(int d = 0; d < 4; d++){
                            int nx = nd[k].x+dx[d], ny = nd[k].y+dy[d];
                            if(nx>=0&&nx<m&&ny>=0&&ny<n&&h[nx][ny]>q[i]){
                                int nid = nx*n+ny;
                                if(~pa[nid]) {
                                    int a = Find(nid), b = Find(id);
                                    if(a != b) {
                                        pa[a] = b;
                                        ans--;
                                    }
                                }
                            }
                        }
                        k--;
                    }
                    if(k<0){
                        for(;i>=0;i--){
                            q[i] = ans;
                        }
                        break;
                    }
                }
                q[i] = ans;
            }
            for(int i = 0; i < Ts; i++) printf("%d ",q[i]);
            putchar('
    ');
        }
        return 0;
    }
  • 相关阅读:
    一分钟 解决Tomcat端口 占用问题
    Java 自定义注解
    Java 解析自定义XML文件
    Junit(手动/自动)加载
    Java思维题
    SSM框架中使用日志框架
    DAC
    SPI接口的FLASH
    晶振测试起振方法
    Jlink不报错的方法
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4776698.html
Copyright © 2011-2022 走看看