题面
答案显然在
−
1
,
0
,
1
,
2
-1,0,1,2
−1,0,1,2之中,因为如果不是
−
1
,
0
,
1
-1,0,1
−1,0,1的话一定可以在一个角落的位置放两个蛐蛐达成目的。
若答案为
−
1
-1
−1,则跳蚤数量小于
2
2
2或者两个跳蚤不相邻。
若答案不为
−
1
-1
−1,则将相邻的跳蚤连边,若图不连通则答案为
0
0
0,若图连通且存在割点则答案为
1
1
1,否则答案为
2
2
2。
实际上跳蚤数量很多,直接连边不现实。将所有蛐蛐周围的八个跳蚤取出,并取出其所在行、所在列最靠边的四个跳蚤,再在整个矩形的四个角每个角取出四个跳蚤。把取出的跳蚤作为关键跳蚤,关键跳蚤在同一行或同一列且中间没有蛐蛐或其他跳蚤就连边,可以建出点数、边数与蛐蛐数量同阶的等效图。
时间复杂度
O
(
∑
c
log
2
c
)
O(\sum c \log_2c)
O(∑clog2c),空间复杂度
O
(
c
)
O(c)
O(c)
#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
#define R register int
#define I inline
#define N 1300020
int cx[100000],cy[100000],cid[100000],dfn[N],low[N],px[N],py[N],lf[N],pid[N],ct;
vector<int>G[N];
bool in[N];
I bool CompareCX(int x,int y){
if(cx[x]==cx[y]){
return cy[x]<cy[y];
}
return cx[x]<cx[y];
}
I bool CompareCY(int x,int y){
if(cy[x]==cy[y]){
return cx[x]<cx[y];
}
return cy[x]<cy[y];
}
I bool ComparePX(int x,int y){
if(px[x]==px[y]){
return py[x]<py[y];
}
return px[x]<px[y];
}
I bool ComparePY(int x,int y){
if(py[x]==py[y]){
return px[x]<px[y];
}
return py[x]<py[y];
}
I void Insert(int x,int y,int r,const int n,const int m){
for(R i=-r;i<=r;i++){
for(R j=-r;j<=r;j++){
if(x>-i&&x+i<=n&&y>-j&&y+j<=m){
px[ct]=x+i;
py[ct]=y+j;
pid[ct]=ct;
ct++;
}
}
}
}
I void Link(int x,int y){
G[x].push_back(y);
G[y].push_back(x);
}
I void Tarjan(int x,int F,int&tot,bool&tag){
in[x]=true;
ct++;
dfn[x]=low[x]=ct;
tot++;
int cur=0;
for(auto T:G[x]){
if(dfn[T]==0){
Tarjan(T,x,tot,tag);
if(low[T]<low[x]){
low[x]=low[T];
}
if(low[T]>=dfn[x]){
cur++;
}
}else if(T!=F&&in[T]==true&&dfn[T]<low[x]){
low[x]=dfn[T];
}
}
in[x]=false;
if(cur>1||F!=-1&&cur>0){
tag=true;
}
}
I void Solve(){
ct=0;
int n,m,c,t=0,q=0,x,y;
scanf("%d%d%d",&n,&m,&c);
Insert(1,1,1,n,m);
Insert(1,m,1,n,m);
Insert(n,1,1,n,m);
Insert(n,m,1,n,m);
for(R i=0;i!=c;i++){
scanf("%d%d",cx+i,cy+i);
cid[i]=i;
Insert(cx[i],cy[i],1,n,m);
Insert(cx[i],1,0,n,m);
Insert(cx[i],m,0,n,m);
Insert(1,cy[i],0,n,m);
Insert(n,cy[i],0,n,m);
}
sort(cid,cid+c,CompareCX);
sort(pid,pid+ct,ComparePX);
for(R i=0;i!=ct;i++){
x=px[pid[i]];
y=py[pid[i]];
if(q==0||px[pid[q-1]]!=x||py[pid[q-1]]!=y){
while(t!=c&&(cx[cid[t]]<x||cx[cid[t]]==x&&cy[cid[t]]<y)){
t++;
}
if(t==c||cx[cid[t]]!=px[pid[i]]||cy[cid[t]]!=py[pid[i]]){
pid[q]=pid[i];
lf[q]=t;
q++;
}
}
}
for(R i=0;i!=q;i++){
G[pid[i]].clear();
dfn[pid[i]]=0;
}
if(q<2){
puts("-1");
return;
}
for(R i=1;i!=q;i++){
int l=lf[i-1];
if(px[pid[i-1]]==px[pid[i]]&&(l==c||cx[cid[l]]>px[pid[i]]||cx[cid[l]]==px[pid[i]]&&cy[cid[l]]>py[pid[i]])){
Link(pid[i-1],pid[i]);
}
}
sort(pid,pid+q,ComparePY);
sort(cid,cid+c,CompareCY);
t=0;
for(R i=0;i!=q;i++){
x=px[pid[i]];
y=py[pid[i]];
while(t!=c&&(cy[cid[t]]<y||cy[cid[t]]==y&&cx[cid[t]]<x)){
t++;
}
lf[i]=t;
}
for(R i=1;i!=q;i++){
int l=lf[i-1];
if(py[pid[i-1]]==py[pid[i]]&&(l==c||cy[cid[l]]>py[pid[i]]||cy[cid[l]]==py[pid[i]]&&cx[cid[l]]>px[pid[i]])){
Link(pid[i-1],pid[i]);
}
}
t=ct=0;
bool tag=false;
Tarjan(pid[0],-1,t,tag);
if(t!=q){
puts("0");
}else if(q==2&&G[pid[0]].empty()==false){
puts("-1");
}else if(tag==true){
puts("1");
}else{
puts("2");
}
}
int main(){
int t;
scanf("%d",&t);
for(R i=0;i!=t;i++){
Solve();
}
return 0;
}