题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5652
题意:一张n*m个格子的点,0表示可走,1表示堵塞。每个节点都是四方向走。开始输入初始状态方格,之后输入Q个操作,表示第(x,y)个格子由0变为1;问你在第几次时不能由最下的一行到最上面的一行。中国在最上面一行的上面,印度在最下面一行的下面;如果最终还是连通的,输出-1;
思路:直接离线逆序处理,用并查集维护;
#include<bits/stdc++.h> using namespace std; #define rep0(i,l,r) for(int i = (l);i < (r);i++) #define rep1(i,l,r) for(int i = (l);i <= (r);i++) #define rep_0(i,r,l) for(int i = (r);i > (l);i--) #define rep_1(i,r,l) for(int i = (r);i >= (l);i--) #define MS0(a) memset(a,0,sizeof(a)) #define MS1(a) memset(a,-1,sizeof(a)) #define MSi(a) memset(a,0x3f,sizeof(a)) #define inf 0x3f3f3f3f #define lson l, m, rt << 1 #define rson m+1, r, rt << 1|1 typedef pair<int,int> PII; #define A first #define B second #define MK make_pair typedef __int64 ll; typedef unsigned int uint; template<typename T> void read1(T &m) { T x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} m = x*f; } template<typename T> void read2(T &a,T &b){read1(a);read1(b);} template<typename T> void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);} template<typename T> void out(T a) { if(a>9) out(a/10); putchar(a%10+'0'); } int T,kase = 1,i,j,k,n,m; const int N = 507; char s[N][N]; queue<PII> pq; inline bool check(int nx,int ny) { if(nx < 0 || nx >= n || ny < 0 || ny >= m) return false; return true; } int dir[2][4] = {{0,1,0,-1},{1,0,-1,0}}; int f[N*N]; int Find(int a){return a==f[a]?f[a]:f[a]=Find(f[a]);} void _union(int a,int b){int p = Find(a),q = Find(b);f[p] = q;} int idx(int r,int c) {return r*m+c;} void BFS(int r,int c) { pq.push({r,c}); int d = Find(idx(r,c)); while(!pq.empty()){ r = pq.front().A,c = pq.front().B;pq.pop(); for(int i = 0;i < 4;i++){ int x = r + dir[0][i] , y = c + dir[1][i]; int id = Find(idx(x,y)); if(!check(x,y) || s[x][y] == '1' || id == d) continue; f[id] = d; pq.push({x,y}); } } } int x[N*N],y[N*N]; int main() { //freopen("data.txt","r",stdin); //freopen("out.txt","w",stdout); read1(T); while(T--){ read2(n,m); int tot = n*m; rep1(i,0,tot+2) f[i] = i; rep0(i,0,n) scanf("%s",s[i]); int Q; read1(Q); rep1(i,1,Q){ read2(x[i],y[i]); s[x[i]][y[i]] = '1'; } rep0(i,0,n) rep0(j,0,m)if(s[i][j] == '0'){ int index = idx(i,j); if(f[index] == index){ BFS(i,j); } } rep0(i,0,m) _union(i,tot+1); rep0(i,0,m) _union(idx(n-1,i),tot+2); if(f[tot+1] == f[tot+2]){ puts("-1"); continue; } rep_1(i,Q,1){ s[x[i]][y[i]] = '0'; BFS(x[i],y[i]); if(Find(tot+1) == Find(tot+2)){ out(i); puts(""); break; } } } return 0; }