• LOJ#2084. 「NOI2016」网格


    $n,m leq 1e9$,$n*m$的网格中有$c leq 1e5$个是黑的,其他是白的。问:使至少两个白的不连通,最少需要再把几个白的涂黑。

    可以发现答案是-1,0,1,2啦。-1要么没白的,要么一个白的,要么两个相邻白的。如果是两个不相邻白的答案就是0,这些可以特判掉。

    其他的情况,可以建个图判连通、判割点。但网格太大了,可以发现连通的话只要关心所有黑点的周围八个白点之间的连通性即可,于是就记下这些点,离散化完分别按$x$和$y$排序来连边。但这样仍不能判割点,比如

    0 0 0 0 0 0 0

    0 0 0 0 0 0 0

    0 0 0 0 0 0 0

    0 0 0 0 0 0 1

    0 0 0 0 0 0 0

    0 0 0 0 0 0 0

    0 0 0 0 0 0 0

    这样,只把

    0 0

    0 1

    0 0

    拿出来建图,会出现3个割点,但不是我们想要的。为避免这种情况,需要把离散化后的周围区域再围一圈。变成这样:

    0 0 0

    0 0 0

    0 0 1

    0 0 0

    0 0 0

    注意到有些边界上的点不能“围”,比如上面例子,右边不能再围一圈。至于怎么围,其实离散化之前,把1,n加入$x$离散化数组中,1,m加入$y$离散化数组中,就可以直接围了,用hash保证不要重复加点即可。

    然而,n=1和m=1需要特殊判断。。我就问出题人,出这种大分类大模拟大特判题是何居心。。

      1 //#include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 //#include<math.h>
      5 //#include<set>
      6 //#include<queue>
      7 //#include<bitset>
      8 //#include<vector>
      9 #include<algorithm>
     10 #include<stdlib.h>
     11 using namespace std;
     12 
     13 #define LL long long
     14 int qread()
     15 {
     16     char c; int s=0,f=1; while ((c=getchar())<'0' || c>'9') (c=='-') && (f=-1);
     17     do s=s*10+c-'0'; while ((c=getchar())>='0' && c<='9'); return s*f;
     18 }
     19 
     20 //Pay attention to '-' , LL and double of qread!!!!
     21 
     22 int T,n,m,c;
     23 #define maxn 2400011
     24 #define maxm 10000011
     25 
     26 int Abs(int x) {return x>0?x:-x;}
     27 
     28 struct Poi
     29 {
     30     int x,y,id;
     31     bool operator == (const Poi &b) const {return x==b.x && y==b.y;}
     32 }cc[maxn];
     33 bool cmpx(const Poi &a,const Poi &b) {return a.x<b.x || (a.x==b.x && a.y<b.y);}
     34 bool cmpy(const Poi &a,const Poi &b) {return a.y<b.y || (a.y==b.y && a.x<b.x);}
     35 
     36 int px[maxn],py[maxn],lx,ly;
     37 
     38 #define maxh 1000007
     39 struct Hash
     40 {
     41     struct Edge{int to,x,y,next;}edge[maxn]; int first[maxh],le;
     42     void clear() {memset(first,0,sizeof(first)); le=2;}
     43     int geth(int x,int y) {return (x*1000000000ll+y)%maxh;}
     44     void in(int x,int y,int id)
     45     {int h=geth(x,y); Edge &e=edge[le]; e.to=id; e.x=x; e.y=y; e.next=first[h]; first[h]=le++;}
     46     void insert(int x,int y,int id) {if (!~find(x,y)) in(x,y,id);}
     47     int find(int x,int y)
     48     {
     49         int h=geth(x,y);
     50         for (int i=first[h];i;i=edge[i].next) if (edge[i].x==x && edge[i].y==y) return edge[i].to;
     51         return -1;
     52     }
     53 }h,hh;
     54 
     55 const int dx[]={-1,0,1,-1,1,-1,0,1},
     56 dy[]={-1,-1,-1,0,0,1,1,1},
     57 ddx[]={-1,1,0,0},ddy[]={0,0,-1,1};
     58 
     59 int TOT,ANS,dfn[maxn],Time,low[maxn],top; Poi sta[maxn];
     60 struct Edge{int to,next;}edge[maxm]; int first[maxn],le=2;
     61 void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
     62 void insert(int x,int y) {in(x,y); in(y,x);}
     63 
     64 void tarjan(int id,int fa)
     65 {
     66     TOT++;
     67     int son=0;
     68     dfn[id]=low[id]=++Time;
     69     for (int i=first[id];i;i=edge[i].next)
     70     {
     71         Edge &e=edge[i]; int u=e.to;
     72         if (!dfn[u])
     73         {
     74             sta[++top]=(Poi){id,u,0};
     75             son++;
     76             tarjan(u,id);
     77             low[id]=min(low[id],low[u]);
     78             if (low[u]>=dfn[id])
     79             {
     80 //                cout<<id<<' '<<u<<endl;
     81                 if (fa) ANS=1;
     82                 while (sta[top].x!=id || sta[top].y!=u) top--;
     83                 top--;
     84             }
     85         }
     86         else if (u!=fa && dfn[u]<dfn[id])
     87         {
     88             sta[++top]=(Poi){id,u,0};
     89             low[id]=min(low[id],dfn[u]);
     90         }
     91     }
     92     if (fa==0 && son>1) ANS=1;
     93 }
     94 
     95 int main()
     96 {
     97     T=qread();
     98     while (T--)
     99     {
    100         n=qread(); m=qread(); c=qread();
    101         for (int i=1;i<=c;i++) {cc[i].x=qread(); cc[i].y=qread();}
    102         if (1ll*n*m-c<2) puts("-1");
    103         else if (1ll*n*m-c==2)
    104         {
    105             if (c==0) {puts("-1"); continue;}
    106             sort(cc+1,cc+1+c,cmpx);
    107             int x1=0,x2=0,y1,y2;
    108             for (int x=1,y=1,i=1;i<=c;i++,x+=(y==m),y=y==m?1:y+1)
    109             {
    110                 if (cc[i].x!=x || cc[i].y!=y)
    111                 {
    112                     if (!x1) x1=x,y1=y;
    113                     else x2=x,y2=y;
    114                     i--;
    115                 }
    116             }
    117             if (x1==0) {x1=n; y1=m-1; x2=n; y2=m;}
    118             else if (x2==0) {x2=n; y2=m;}
    119             if (Abs(x1-x2)+Abs(y1-y2)==1) puts("-1");
    120             else puts("0");
    121         }
    122         else
    123         {
    124             if (c==0)
    125             {
    126                 if (n==1 || m==1) puts("1");
    127                 else puts("2");
    128                 continue;
    129             }
    130             
    131             int tc=c;
    132             for (int i=1;i<=c;i++) cc[i].id=0;
    133             lx=ly=0;
    134             hh.clear();
    135             for (int i=1;i<=c;i++) hh.insert(cc[i].x,cc[i].y,i);
    136             for (int i=1,tmp=c;i<=tmp;i++)
    137             {
    138                 px[++lx]=cc[i].x; py[++ly]=cc[i].y;
    139                 for (int j=0;j<8;j++)
    140                 {
    141                     int xx=dx[j]+cc[i].x,yy=dy[j]+cc[i].y;
    142                     if (xx<=0 || xx>n || yy<=0 || yy>m || ~hh.find(xx,yy)) continue;
    143                     c++; cc[c].x=xx; cc[c].y=yy; cc[c].id=cc[c-1].id+1; hh.insert(xx,yy,0);
    144                     px[++lx]=xx; py[++ly]=yy;
    145                 }
    146             }
    147             
    148             px[++lx]=1; px[++lx]=n; sort(px+1,px+1+lx); lx=unique(px+1,px+1+lx)-px-1;
    149             py[++ly]=1; py[++ly]=m; sort(py+1,py+1+ly); ly=unique(py+1,py+1+ly)-py-1;
    150             for (int i=1;i<=c;i++) cc[i].x=lower_bound(px+1,px+1+lx,cc[i].x)-px,
    151             cc[i].y=lower_bound(py+1,py+1+ly,cc[i].y)-py;
    152             
    153             hh.clear(); for (int i=1;i<=c;i++) hh.insert(cc[i].x,cc[i].y,cc[i].id);
    154             for (int i=1;i<=ly;i++) if (!~hh.find(1,i))
    155             {cc[c+1]=(Poi){1,i,cc[c].id+1}; c++; hh.insert(cc[c].x,cc[c].y,cc[c].id);}
    156             for (int i=1;i<=ly;i++) if (!~hh.find(lx,i))
    157             {cc[c+1]=(Poi){lx,i,cc[c].id+1}; c++; hh.insert(cc[c].x,cc[c].y,cc[c].id);}
    158             for (int i=1;i<=lx;i++) if (!~hh.find(i,1))
    159             {cc[c+1]=(Poi){i,1,cc[c].id+1}; c++; hh.insert(cc[c].x,cc[c].y,cc[c].id);}
    160             for (int i=1;i<=lx;i++) if (!~hh.find(i,ly))
    161             {cc[c+1]=(Poi){i,ly,cc[c].id+1}; c++; hh.insert(cc[c].x,cc[c].y,cc[c].id);}
    162             
    163             memset(first,0,sizeof(first)); le=2;
    164             sort(cc+1,cc+1+c,cmpx);
    165             for (int i=1;i<c;i++) if (cc[i].id && cc[i+1].id && cc[i].x==cc[i+1].x) insert(cc[i].id,cc[i+1].id);
    166             sort(cc+1,cc+1+c,cmpy);
    167             for (int i=1;i<c;i++) if (cc[i].id && cc[i+1].id && cc[i].y==cc[i+1].y) insert(cc[i].id,cc[i+1].id);
    168             
    169             TOT=ANS=Time=top=0;
    170             memset(dfn,0,sizeof(dfn));
    171             tarjan(1,0);
    172             if (TOT<c-tc) puts("0");
    173             else if ((n==1 || m==1) && (n*m>TOT)) puts("1");
    174             else if (ANS) puts("1"); else puts("2");
    175         }
    176     }
    177     
    178     return 0;
    179 }
    View Code
  • 相关阅读:
    B01-java学习-阶段2-面向对象
    A11-java学习-二维数组-面向对象概念-类的编写-测试类的编写-创建对象-使用对象-递归
    09-java学习-数组-冒泡排序-选择排序-数组工具类编写-查找-扩容
    08-java学习-数组-增强for循环-数组与方法-main函数参数
    07-java学习-方法重载-idea集成开发工具学习-项目-模块-包
    执行SQL语句---SELECT
    执行SQL语句---INSERT/UPDATE/DELETE
    undefined reference to `mysql_init'解决办法
    ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
    网络编程(三)---数据报套接字
  • 原文地址:https://www.cnblogs.com/Blue233333/p/9251521.html
Copyright © 2020-2023  润新知