题目分析:
答案显然只有{-1,0,1,2}四种。
对于答案等于-1的情况,只有两种情况,一种是只剩一只跳蚤,另一种是只剩两只跳蚤且他们四连通,这个很好判。
对于答案等于0的情况,那说明联通块大于1,把图离散出来连边并查集判就可以了。
对于答案等于1的情况,我们要考虑唯一的联通块是否存在割顶,具体的,我们发现答案只可能是有蛐蛐的格子旁边的八个格子(n=1或m=1除外),那么把它们提取出来单独建点,而其它的离散,跑一边割顶就可以做了。
剩下的输出2.
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 2012000; 5 6 int n,m,c,tot; 7 pair<int,int> pr[maxn]; 8 vector<pair<int,int> > vec[maxn]; 9 int arr[maxn],mlgb[maxn],isg[maxn]; 10 vector<int> g[maxn]; 11 int dx[8]={0,0,1,-1,1,-1,1,-1}; 12 int dy[8]={1,-1,0,0,1,-1,-1,1}; 13 int chk,pre[maxn]; 14 int low[maxn],dfn[maxn],cl,fa[maxn]; 15 16 void init(){ 17 memset(pr,0,sizeof(pr)); 18 for(int i=0;i<=tot;i++) low[i]=dfn[i]=fa[i]=isg[i]=arr[i]=0; 19 for(int i=0;i<=tot;i++) vec[i].clear(),g[i].clear(); 20 cl = chk = n = m = c = tot = 0; 21 } 22 23 int found(int x){ 24 int rx = x; while(pre[rx] != rx) rx = pre[rx]; 25 while(pre[x] != rx){int tmp = pre[x]; pre[x] = rx; x = tmp;} 26 return rx; 27 } 28 29 int pd0(){ 30 sort(pr+1,pr+c+1);pr[0] = make_pair(0,m+10); 31 int tnum = 0,pnum = 0; 32 int zt = 0; 33 for(int i=1;i<=c;i++) arr[++zt]=pr[i].first-1,arr[++zt]=pr[i].first+1,arr[++zt]=pr[i].first; 34 sort(arr+1,arr+zt+1); zt = unique(arr+1,arr+zt+1)-arr-1; 35 while(arr[zt] == n+1)zt--; 36 for(int i=1;i<=zt;i++){ 37 if(arr[i] == 0) continue; 38 if(arr[i] != arr[i-1]+1){vec[++tnum].push_back(make_pair(1,m));tot++;} 39 tnum++; 40 int lst = lower_bound(pr+1,pr+c+1,make_pair(arr[i]-1,0))-pr; 41 int now = lower_bound(pr+1,pr+c+1,make_pair(arr[i],0))-pr; 42 if(pr[now].first != arr[i]) now = 0; 43 int imp=0;while(lst<=c&&pr[lst].first<=arr[i]+1) mlgb[++imp]=pr[lst].second,lst++; 44 sort(mlgb+1,mlgb+imp+1); imp = unique(mlgb+1,mlgb+imp+1)-mlgb-1; 45 int z = 1;int j = now,k = 1; 46 while(z <= m){ 47 if(k > imp){vec[tnum].push_back(make_pair(z,m));tot++;z=m+1;break;} 48 while(pr[j].first==arr[i]&&pr[j].second<mlgb[k])j++; 49 if(z < mlgb[k]-1){vec[tnum].push_back(make_pair(z,mlgb[k]-2));tot++;z = mlgb[k]-1;} 50 if(z < mlgb[k]){isg[++tot]=1;vec[tnum].push_back(make_pair(z,mlgb[k]-1));z = mlgb[k];} 51 if(z==mlgb[k]&&(!(pr[j].first==arr[i]&&pr[j].second==mlgb[k]))){ 52 isg[++tot]=1;vec[tnum].push_back(make_pair(z,mlgb[k]));z = mlgb[k]+1; 53 }else z = mlgb[k]+1; 54 if(z > m) break; 55 while(pr[j].first==arr[i]&&pr[j].second<mlgb[k]+1)j++; 56 if(!(pr[j].first==arr[i]&&pr[j].second==mlgb[k]+1)){ 57 isg[++tot]=1;vec[tnum].push_back(make_pair(z,mlgb[k]+1));z = mlgb[k]+2; 58 } 59 k++; 60 } 61 } 62 if(arr[zt] != n){vec[++tnum].push_back(make_pair(1,m));tot++;} 63 for(int i=0;i<tot;i++) pre[i] = i; 64 for(int i=1;i<tnum;i++){ 65 int k = 0; 66 for(int j=0;j<vec[i].size();j++){ 67 while(k<vec[i+1].size()&&vec[i+1][k].second < vec[i][j].first) k++; 68 while(k<vec[i+1].size()&&vec[i+1][k].second <= vec[i][j].second){ 69 g[pnum+j].push_back(pnum+vec[i].size()+k); 70 g[pnum+vec[i].size()+k].push_back(pnum+j); 71 pre[found(pnum+j)] = found(pnum+vec[i].size()+k); k++; 72 } 73 if(k<vec[i+1].size()&&vec[i+1][k].first <= vec[i][j].second){ 74 g[pnum+j].push_back(pnum+vec[i].size()+k); 75 g[pnum+vec[i].size()+k].push_back(pnum+j); 76 pre[found(pnum+j)] = found(pnum+vec[i].size()+k); 77 } 78 } 79 pnum += vec[i].size(); 80 } 81 pnum = 0; 82 for(int i=1;i<=tnum;i++){ 83 for(int j=1;j<vec[i].size();j++){ 84 if(vec[i][j].first == vec[i][j-1].second+1){ 85 g[pnum+j].push_back(pnum+j-1); 86 g[pnum+j-1].push_back(pnum+j); 87 pre[found(pnum+j)] = found(pnum+j-1); 88 } 89 } 90 pnum += vec[i].size(); 91 } 92 int hh = 0; 93 for(int i=0;i<tot;i++){if(pre[i] == i) hh++;} 94 if(hh>1) return 1; else return 0; 95 } 96 97 void Tarjan(int now){ 98 low[now] = dfn[now] = ++cl; 99 for(int i=0;i<g[now].size();i++){ 100 if(g[now][i] == fa[now]) continue; 101 if(dfn[g[now][i]] > dfn[now]) continue; 102 if(dfn[g[now][i]] == 0){ 103 fa[g[now][i]] = now;Tarjan(g[now][i]); 104 low[now] = min(low[now],low[g[now][i]]); 105 }else{low[now] = min(low[now],dfn[g[now][i]]);} 106 } 107 if(isg[now+1]==0)return; 108 if(now != 0){ 109 for(int i=0;i<g[now].size();i++){ 110 if(fa[g[now][i]] != now) continue; 111 if(low[g[now][i]] >= dfn[now]){chk=1;} 112 } 113 }else{ 114 int nh = 0; 115 for(int i=0;i<g[now].size();i++){if(fa[g[now][i]] == now){nh++;}} 116 if(nh > 1) chk++; 117 } 118 } 119 120 void read(){ 121 scanf("%d%d%d",&n,&m,&c); 122 for(int i=1;i<=c;i++){scanf("%d%d",&pr[i].first,&pr[i].second);} 123 } 124 125 void work(){ 126 if(1ll*n*m-c <= 1){puts("-1");return;} 127 if(1ll*n*m-c == 2){ 128 sort(pr+1,pr+c+1); pair<int,int> l1,l2; 129 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ 130 int z = lower_bound(pr+1,pr+c+1,make_pair(i,j))-pr; 131 if(pr[z] == make_pair(i,j)) continue; 132 if(l1 != make_pair(0,0)) l2=make_pair(i,j); else l1=make_pair(i,j); 133 } 134 if(abs(l1.first-l2.first)+abs(l1.second-l2.second)==1){puts("-1");} 135 else puts("0"); 136 return; 137 } 138 if(pd0()) {puts("0");return;} 139 if(n == 1 || m == 1){puts("1");return;} 140 Tarjan(0); 141 if(chk){puts("1");return;} 142 else puts("2"); 143 } 144 145 int main(){ 146 int Tmp; scanf("%d",&Tmp); 147 while(Tmp--){ 148 init(); 149 read(); 150 work(); 151 } 152 return 0; 153 }