题目链接:看这里吧,中文题
解法: 以前做过,BC的一道题,今天复习并查集重写一次。 然后比较显然的就是二分+判断是否连通,判断是否连通用并查集和bfs都可以。

//HDU 5652

#include <bits/stdc++.h>
using namespace std;
const int maxn = 510;
int n, m, q, vis[maxn][maxn];
char s[maxn][maxn];
pair <int, int> d[maxn*maxn];
int dir[4][2] = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
namespace dsu{
    int fa[maxn*maxn];
    inline void init(){for(int i = 0; i <= n*m + 1; i++) fa[i] = i;}
    inline int find_set(int x){if(x == fa[x]) return x; else return fa[x] = find_set(fa[x]);}
    inline void union_set(int x, int y){x = find_set(x), y = find_set(y); if(x != y) fa[x] = y;}
}
using namespace dsu;

int check(int t)
{
    init();
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            if(s[i][j] == '1') vis[i][j] = 1;
            else vis[i][j] = 0;
    for(int i = 1; i <= t ;i++){
        vis[d[i].first][d[i].second] = 1;
    }
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(vis[i][j] == 1) continue;
            for(int k = 0; k < 4; k++){
                int tx = i + dir[k][0], ty = j + dir[k][1];
                if(ty <= 0 || ty > m) continue;
                if(tx == 0) union_set((i-1)*m + j, 0);
                else if(tx == n+1) union_set((i-1)*m + j, n*m+1);
                else{
                    if(vis[tx][ty]) continue;
                    union_set((i-1)*m + j, (tx-1)*m+ty);
                }
            }
        }
    }
    if(find_set(0) == find_set(n*m+1)) return 1;
    else return 0;
}

int main()
{
    int T; scanf("%d", &T);
    while(T--){
        memset(vis, 0, sizeof(vis));
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++) scanf("%s", s[i]+1);
        scanf("%d", &q);
        for(int i = 1; i <= q; i++){
            scanf("%d%d", &d[i].first, &d[i].second);
            d[i].first++, d[i].second++;
        }
        if(check(q)){
            puts("-1");
            return 0;
        }
        int l = 0, r = q , ans = 0;
        while(l <= r){
            int mid = (l + r ) / 2;
            if(!check(mid)) r = mid - 1, ans = mid;
            else l = mid + 1;
        }
        printf("%d\n", ans);
    }
    return 0;
}