# LOJ#2084. 「NOI2016」网格

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

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

0 0 0

0 0 0

0 0 1

0 0 0

0 0 0

  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
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 {
98     while (T--)
99     {
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

posted @ 2018-07-01 21:57  Blue233333  阅读(289)  评论(0编辑  收藏  举报