zoukankan      html  css  js  c++  java
  • (并查集)Codeforces 325 D-Reclamation

    借用 链接 的题意和解法分析的图片。

    对于这种环的形式,先用常用的手段复制一份在右边。每次加点的过程只要看加完之后能不能通过已有的格子联通,如果联通则显然已经形成了一个环。这里判断联通我采用的办法是,分别看两个点八个方向是否联通的无脑办法。想法很明确,但实现的过程中要注意一些细节,如列坐标<=0或>2*m的处理。

      1 #include <iostream>
      2 #include <string>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <queue>
      8 #include <set>
      9 #include <map>
     10 #include <list>
     11 #include <vector>
     12 #include <stack>
     13 #define mp make_pair
     14 //#define P make_pair
     15 #define MIN(a,b) (a>b?b:a)
     16 //#define MAX(a,b) (a>b?a:b)
     17 typedef long long ll;
     18 typedef unsigned long long ull;
     19 const int MAX=18e6+5;
     20 const int MAX_V=1e3+5;
     21 const int INF=1e9+5;
     22 const ll INF2=4e18+5;
     23 const double M=4e18;
     24 using namespace std;
     25 const int MOD=1e9+7;
     26 typedef pair<ll,int> pii;
     27 const double eps=0.000000001;
     28 #define rank rankk
     29 int an;
     30 int par[MAX];//父亲
     31 int rank[MAX];//树的高度
     32 //初始化n个元素
     33 void init(int n)
     34 {
     35     for(int i=0;i<n;i++)
     36     {
     37         par[i]=i;
     38         rank[i]=0;
     39     }
     40 }
     41 //查询树的根,期间加入了路径压缩
     42 int find(int x)
     43 {
     44     if(par[x]==x)
     45         return x;
     46     else
     47         return par[x]=find(par[x]);
     48 }
     49 //合并x和y所属的集合
     50 void unite(int x,int y)
     51 {
     52     x=find(x);
     53     y=find(y);
     54     if(x==y)
     55         return ;
     56     if(rank[x]<rank[y])
     57         par[x]=y;
     58     else
     59     {
     60         par[y]=x;
     61         if(rank[x]==rank[y])
     62             rank[x]++;
     63     }
     64 }
     65 //判断x和y是否属于同一个集合
     66 bool same(int x,int y)
     67 {
     68     return find(x)==find(y);
     69 }
     70 int n,m,q;
     71 int a[MAX];
     72 int dx[8]={-1,-1,-1,0,0,1,1,1};
     73 int dy[8]={-1,0,1,-1,1,-1,0,1};
     74 bool vi[3005][6005];
     75 int idx(int x,int y)//x行y列
     76 {
     77     return (x-1)*2*m+y;
     78 }
     79 bool check(int x,int &y)
     80 {
     81     return x>=1&&x<=n&&y>=1&&y<=2*m;
     82 }
     83 int solve(int x,int y)
     84 {
     85     int x2=x,y2=y+m;
     86     for(int i=0;i<8;i++)
     87     {
     88         int x1=x+dx[i],y1=y+dy[i];
     89         if(y1<1)
     90             y1+=2*m;
     91         else if(y1>2*m)
     92             y1-=2*m;
     93         if(check(x1,y1)&&vi[x1][y1])
     94         {
     95             for(int j=0;j<8;j++)
     96             {
     97                 int x3=x2+dx[j],y3=y2+dy[j];
     98                 if(check(x3,y3)&&vi[x3][y3])
     99                     if(same(idx(x3,y3),idx(x1,y1)))
    100                        return 0;
    101             }
    102         }
    103     }
    104     return 1;
    105 }
    106 int main()
    107 {
    108     scanf("%d%d%d",&n,&m,&q);
    109     if(m==1)
    110         return 0*printf("0
    ");
    111     init(2*n*m+3);
    112     int Max=2*m;
    113     while(q--)
    114     {
    115         int x,y;
    116         scanf("%d%d",&x,&y);
    117             if(solve(x,y))
    118             {
    119                 vi[x][y]=vi[x][y+m]=true;
    120                 ++an;
    121                 for(int i=0;i<8;i++)
    122                 {
    123                     int x1=x+dx[i],y1=y+dy[i];
    124                     if(y1<=0)
    125                         y1+=Max;
    126                     else if(y1>Max)
    127                         y1-=Max;
    128                     if(check(x1,y1)&&vi[x1][y1])
    129                         unite(idx(x,y),idx(x1,y1));
    130                     y1+=m;
    131                     if(y1<=0)
    132                         y1+=Max;
    133                     else if(y1>Max)
    134                         y1-=Max;
    135                     if(check(x1,y1)&&vi[x1][y1])
    136                         unite(idx(x,y+m),idx(x1,y1));
    137                 }
    138             }
    139     }
    140     printf("%d
    ",an);
    141     return 0 ;
    142 }
  • 相关阅读:
    Windows Azure Storage (17) Azure Storage读取访问地域冗余(Read Access – Geo Redundant Storage, RA-GRS)
    SQL Azure (15) SQL Azure 新的规格
    Azure China (5) 管理Azure China Powershell
    Azure China (4) 管理Azure China Storage Account
    Azure China (3) 使用Visual Studio 2013证书发布Cloud Service至Azure China
    Azure China (2) Azure China管理界面初探
    Azure China (1) Azure公有云落地中国
    SQL Azure (14) 将云端SQL Azure中的数据库备份到本地SQL Server
    [New Portal]Windows Azure Virtual Machine (23) 使用Storage Space,提高Virtual Machine磁盘的IOPS
    Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())的注意点
  • 原文地址:https://www.cnblogs.com/quintessence/p/6936752.html
Copyright © 2011-2022 走看看