难绷,交了20几遍都没过,目前最高88pts……
根据数据点提示,是在有割点但联通的图上把图判成了不联通,对拍小样例没出锅,大样例下载下来没法手玩,已经6K了QAQ……
强神可以重点帮我看看check0部分,目前排除了多测不清空的情况
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void read(int &p){
p=0;int f=1;char z=getchar();
while(z>'9'||z<'0'){if(z=='-')f=-1;z=getchar();}
while(z>='0'&&z<='9'){p=(p<<1)+(p<<3)+z-'0';z=getchar();}
p*=f;
}
int t,n,m,c,x[100005],y[100005],h[2500206]={},h2[2500206]={},tp(0),tp2(0);
ll N,M,X,Y,mod=1000003,st[2500050],st2[2500050];
void cl(){
while(tp){
h[st[tp--]]=0;
}
}
void has(int xx,int yy,int p){
X=xx,Y=yy;
X=(X-1)*M+Y;st[++tp]=X%mod;
h[X%mod]=p;
}
void has1(int xx,int yy){
X=xx,Y=yy;
X=(X-1)*M+Y;
h[X%mod]=0;
}
int ask(int xx,int yy){
X=xx,Y=yy;
X=(X-1)*M+Y;
return h[X%mod];
}
void cl2(){
while(tp2){
h2[st2[tp2--]]=0;
}
}
void has2(int xx,int yy,int p){
X=xx,Y=yy;
X=(X-1)*M+Y;st2[++tp2]=X%mod;
h2[X%mod]=p;//printf("%lld ",X%mod);
}
int ask2(int xx,int yy){
X=xx,Y=yy;
X=(X-1)*M+Y;
return h2[X%mod];
}
bool inn(int xx,int yy){
if(xx<=0||yy<=0||xx>n||yy>m)return true;
return false;
}
bool check_1(){
if(N*M-(ll)c<2ll)return true;
if(N*M-(ll)c>2ll)return false;
cl();
for(int i(1);i<=c;++i)has(x[i],y[i],1);
int u(0),v;
for(int i(1);i<=n;++i){
for(int j(1);j<=m;++j){
if(!ask(i,j)){
if(!u)u=i,v=j;
else{
if((abs(u-i)==1&&v==j)||(abs(v-j)==1&&u==i))return true;
else return false;
}
}
}
}
}
bool b[100005];
int xx0[10]={0,0,0,-1,1,-1,1,-1,1},yy0[10]={0,1,-1,0,0,1,1,-1,-1};
int xx[2500005],yy[2500005],tt;
queue<int>q,e,f;
bool check0(){
memset(b,false,sizeof(b));while(q.size())q.pop();
b[0]=true;tt=0;
for(int i(1),u,v,ans(0);i<=c;++i){
if(b[i])continue;
b[i]=true;q.push(i);cl();tt=0;
while(q.size()){
u=q.front();q.pop();//printf("u:%d %d\n",x[u],y[u]);
for(int j(1);j<=8;++j){
if(inn(x[u]+xx0[j],y[u]+yy0[j]))continue;
v=ask2(x[u]+xx0[j],y[u]+yy0[j]);
if(v){//printf("J:%d %d\n",x[u]+xx0[j],y[u]+yy0[j]);
if(!b[v]){
b[v]=true;
q.push(v);
}
}
else if(!ask(x[u]+xx0[j],y[u]+yy0[j])){
xx[++tt]=x[u]+xx0[j],yy[tt]=y[u]+yy0[j],has(xx[tt],yy[tt],1);
}
}
}//printf("tt:%d \n",tt);
//for(int j(1);j<=tt;++j)printf("xx:%d %d\n",xx[j],yy[j]);
e.push(xx[1]),f.push(yy[1]);has1(xx[1],yy[1]);v=ans=0;
while(e.size()){
u=e.front();e.pop();v=f.front();f.pop();++ans;
for(int j(1);j<=4;++j){//printf("%d %d\n",u,v);
if(!inn(u+xx0[j],v+yy0[j])&&!ask2(u+xx0[j],v+yy0[j])&&ask(u+xx0[j],v+yy0[j])){
has1(u+xx0[j],v+yy0[j]);
e.push(u+xx0[j]),f.push(v+yy0[j]);
}
}
}//printf("ANS:%d\n",ans);
for(int j(1);j<=tt;++j)if(ask(xx[j],yy[j]))return true;
//if(ans<tt)return true;
}
return false;
}
int hd[2500005],nxt[4000006],vi[4000006],cnt(1),num(0);
void link(int xe,int ye){
vi[++cnt]=ye;nxt[cnt]=hd[xe];hd[xe]=cnt;
}
int dfn[2500005],low[2500005],spe;
bool tarjan(int ro,int p,int fa){//printf("p:%d ",p);
dfn[p]=low[p]=++num;
for(int i(hd[p]);i;i=nxt[i]){
if(!dfn[vi[i]]){
if(tarjan(ro,vi[i],p))return true;
low[p]=min(low[p],low[vi[i]]);
if(dfn[p]<=low[vi[i]]){
if(p!=ro){
if(p<=tt)return true;
}
else if(!spe)++spe;
else if(p<=tt)return true;
}
}
else if(vi[i]!=fa)low[p]=min(low[p],dfn[vi[i]]);
}
return false;
}
bool check1(){
memset(b,false,sizeof(b));while(q.size())q.pop();
b[0]=true;tt=0;int u,v;cl();tt=0;
for(int i(1),ans(0);i<=c;++i){
if(b[i])continue;
b[i]=true;q.push(i);
while(q.size()){
u=q.front();q.pop();
for(int j(1);j<=8;++j){
if(inn(x[u]+xx0[j],y[u]+yy0[j]))continue;
v=ask2(x[u]+xx0[j],y[u]+yy0[j]);
if(v){
if(!b[v]){
b[v]=true;
q.push(v);
}
}
else if(!ask(x[u]+xx0[j],y[u]+yy0[j])){
xx[++tt]=x[u]+xx0[j],yy[tt]=y[u]+yy0[j],has(xx[tt],yy[tt],1);
}
}
}
}
int ttt=tt;
for(int j(1);j<=tt;++j){
for(int k(1);k<=8;++k){
u=xx0[k]+xx[j],v=yy0[k]+yy[j];
if(!ask2(u,v)&&!ask(u,v)&&!inn(u,v))has(u,v,1),xx[++ttt]=u,yy[ttt]=v;
}
}//printf("ttt:%d\n",ttt);
memset(hd,0,sizeof(hd));cnt=1;
for(int j(1);j<=ttt;++j)has(xx[j],yy[j],j);//printf("x:%d y:%d\n",xx[j],yy[j]);
for(int j(1);j<=ttt;++j){dfn[j]=low[j]=0;
for(int k(1);k<=4;++k){
u=xx0[k]+xx[j],v=yy0[k]+yy[j];
if(!ask2(u,v)&&ask(u,v)&&!inn(u,v))link(j,ask(u,v));//printf("fr:%d to%d\n",j,ask(u,v));
}
}num=spe=0;//printf("cnt:%d\n",cnt-1);
for(int i(1);i<=ttt;++i){
spe=0;
if(!dfn[i])if(tarjan(i,i,0))return true;
}
return false;
}
int main(){
//freopen("data.in","r",stdin);
//freopen("mine.ans","w",stdout);
read(t);
while(t--){
read(n),read(m),read(c);N=n,M=m;
for(int i(1);i<=c;++i)read(x[i]),read(y[i]);
if(check_1()){
printf("-1\n");
continue;
}
cl2();
for(int i(1);i<=c;++i)has2(x[i],y[i],i);
if(check0()){
printf("0\n");
continue;
}
if(check1()||n==1||m==1){
printf("1\n");
continue;
}
printf("2\n");
}
return 0;
}