• (并查集)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 }
  • 相关阅读:
    HBaseTDG ClientAPI The Basics
    Hadoop TDG 3 – MR Features
    NoSQL Data Modeling Techniques
    配置SharePoint 2010的User Profile Synchronization连接到第三方的LDAP服务
    Failed to load data access DLL, 0x80004005
    如何开放HyperV服务的远程连接权限给别人?
    SharePoint 2010 Search 架构 已完工
    如何对SharePoint里OOB的JavaScript文件进行Debug 之一
    UPA Sync Service启动之后立即自动停止
    SharePoint 2010服务器场的防火墙需要开放哪些端口?
  • 原文地址:https://www.cnblogs.com/quintessence/p/6936752.html
Copyright © 2020-2023  润新知