二分答案+验证,注意一开始就不连通的话输出0
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> using namespace std; const int maxn=500+50; char s[maxn][maxn]; char tmp[maxn][maxn]; bool flag[maxn][maxn]; int dir[4][2]={ {0,1}, {0,-1}, {1,0}, {-1,0} }; struct X { int x,y; }q[maxn*maxn]; int n,m,Q; void read() { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%s",s[i]); scanf("%d",&Q); for(int i=1;i<=Q;i++) scanf("%d%d",&q[i].x,&q[i].y); } bool P(int a,int b) { if(a>=0&&a<n) { if(b>=0&&b<m) { if(tmp[a][b]=='0') { if(flag[a][b]==0) { return 1; } } } } return 0; } void dfs(int x,int y) { flag[x][y]=1; for(int i=0;i<4;i++) { int newx=x+dir[i][0]; int newy=y+dir[i][1]; if(P(newx,newy)) dfs(newx,newy); } } bool f(int year) { for(int i=0;i<n;i++) for(int j=0;j<m;j++) tmp[i][j]=s[i][j]; for(int i=1;i<=year;i++) tmp[q[i].x][q[i].y]='1'; bool fail=1; for(int j=0;j<m;j++) if(tmp[0][j]=='0') fail=0; if(fail) return 1; fail=1; for(int j=0;j<m;j++) if(tmp[n-1][j]=='0') fail=0; if(fail) return 1; memset(flag,0,sizeof flag); for(int j=0;j<m;j++) if(tmp[0][j]=='0') dfs(0,j); fail=1; for(int j=0;j<m;j++) if(tmp[n-1][j]=='0'&&flag[n-1][j]==1) fail=0; return fail; } int main() { int T; scanf("%d",&T); while(T--) { read(); if(f(0)) printf("0 "); else { int ans=-1; int left=1,right=Q; while(left<=right) { int mid=(left+right)/2; if(f(mid)) { ans=mid; right=mid-1; } else { left=mid+1; } } printf("%d ",ans); } } return 0; }