zoukankan      html  css  js  c++  java
  • 【Openjudge】岛屿(并查集)

     题目链接

       此题是并查集。考虑到水位不断上涨,所以将时间倒转。先统计最后一天的联通块个数,每一天浮出水面的块进行计算。复杂度O(玄学)。

       代码如下

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    
    short u[5]={0,0,1,0,-1};
    short w[5]={0,1,0,-1,0};
    
    int n,m;
    
    inline long long read(){
      long long num=0,f=1;
      char ch=getchar();
      while(!isdigit(ch)){
          if(ch=='-')f=-1;
          ch=getchar();
      }
      while(isdigit(ch)){
          num=num*10+ch-'0';
          ch=getchar();
      }
      return num*f;
    }
    
    struct Point{
      short x,y;
      int h;
      bool operator <(const Point &a)const{
         return h
      }
    }mp[10000000];
    int num;
    int Map[3001][3001];
    int que[1000000];
    int ans[1000000];
    int father[10000000];
    bool jd[3001][3001];
    
    int find(int x){
      if(father[x]!=x)father[x]=find(father[x]);
      return father[x];
    }
    
    inline void Union(int x,int y){
      x=find(x);y=find(y);
      father[y]=x;
    }
    
    inline int query(int i,int j){
       return (i-1)*m+j;
    }
    
    int main(){
      n=read(),m=read();
      for(int i=1;i<=n*m+1;++i)    father[i]=i;
      int s;
      for(int i=1;i<=n;++i)
      for(int j=1;j<=m;++j){
          s=read();
          mp[++num]=(Point){i,j,s};
          Map[i][j]=s;
      }
      sort(mp+1,mp+num+1);
      int T=read();
      for(int i=1;i<=T;++i)    que[i]=read();
      int cnt=1;
      for(int i=T;i>=1;--i){
          ans[i]=ans[i+1];
          while(mp[cnt].h>que[i]&&cnt<=n*m){
              jd[mp[cnt].x][mp[cnt].y]=1;
              ans[i]++;
              for(int j=1;j<=4;++j){
                  short x=mp[cnt].x+u[j];
                  short y=mp[cnt].y+w[j];
                  if(x>0&&y>0&&x<=n&&y<=m&&Map[x][y]>que[i]&&jd[x][y]&&find(query(x,y))!=find(query(mp[cnt].x,mp[cnt].y))){
                      Union(query(x,y),query(mp[cnt].x,mp[cnt].y));
                      ans[i]--;
                  }
              }
              cnt++;
          }
      }
      for(int i=1;i<=T;++i)printf("%d ",ans[i]);
      return 0;
    }
  • 相关阅读:
    Word2010如何从指定页设置页码
    十大常见web漏洞及防范
    CSRF攻击与防御
    信息安全常见漏洞类型汇总
    回忆一次校招笔试的题目
    Python操作rabbitmq系列(三):多个接收端消费消息
    Python操作rabbitmq系列(二):多个接收端消费消息
    Python操作rabbitmq系列(一)
    Python操作Redis
    Python连接Redis
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/7467393.html
Copyright © 2011-2022 走看看