1 4 6 011010 000010 100001 001000 7 0 3 1 5 1 3 0 0 1 2 2 4 2 1
4
BFS + 二分
#include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> #include <queue> using namespace std; #define maxn 511 #define move Move char mp[maxn][maxn]; int op[maxn*maxn][2]; int n, m, q; const int move[4][2] = { { 0, 1 }, { 0, -1 }, { 1, 0 }, { -1, 0 } }; bool vis[maxn][maxn]; bool legal(int x, int y) { if (x < 0 || y < 0 || x >= n || y >= m) return 0; return 1; } struct node { int x, y; node(int x, int y) : x(x), y(y) {} node() {} }; node gg[maxn*maxn]; int tou, wei; bool ok(int pos) {//是否联通 memset(vis, 0, sizeof vis); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (mp[i][j] == '1') {//cout << ".." << endl; vis[i][j] = 1; } } } for (int i = 1; i <= pos; i++) { vis[op[i][0]][op[i][1]] = 1; } for (int i = 0; i < m; i++) { if (!vis[0][i]) { tou = wei = 0; gg[wei++] = node(0, i); vis[0][i] = 1; while (tou < wei) { node now = gg[tou++]; //cout << now.x << " " << now.y << endl; for (int i = 0; i < 4; i++) { node next; next.x = now.x + move[i][0]; next.y = now.y + move[i][1]; if (!legal(next.x, next.y) || vis[next.x][next.y]) continue; if (next.x == n - 1) return 1; gg[wei++] = next; vis[next.x][next.y] = 1; } } } } return 0; } int main() { //freopen ("in.txt", "r", stdin); int t; scanf("%d", &t); while (t--) { scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) scanf("%s", mp[i]); scanf("%d", &q); //cout << q << endl; for (int i = 1; i <= q; i++) { scanf("%d%d", &op[i][0], &op[i][1]); } if (!ok(0)) { printf("0\n"); continue; } int l = 1, r = q; while (r - l > 1) { int mid = (l + r) >> 1; if (ok(mid)) l = mid; else r = mid; } if (!ok(r)) printf("%d\n", r); else printf("-1\n"); } return 0; }
二维上的并查集
/**************** *PID: *Auth:Jonariguez ***************** */ #define lson k*2,l,m #define rson k*2+1,m+1,r #define rep(i,s,e) for(i=(s);i<=(e);i++) #define For(j,s,e) For(j=(s);j<(e);j++) #define sc(x) scanf("%d",&x) #define In(x) scanf("%I64d",&x) #define pf(x) printf("%d",x) #define pfn(x) printf("%d\n",(x)) #define Pf(x) printf("%I64d",(x)) #define Pfn(x) printf("%I64d\n",(x)) #define Pc printf(" ") #define PY puts("YES") #define PN puts("NO") #include <stdio.h> #include <string.h> #include <string> #include <math.h> #include <set> #include <map> #include <stack> #include <queue> #include <vector> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; typedef int Ll; Ll quick_pow(Ll a, Ll b, Ll MOD){ a %= MOD; Ll res = 1; while (b){ if (b & 1)res = (res*a) % MOD; b /= 2; a = (a*a) % MOD; }return res; } const int maxn = 500 + 10; int mp[maxn][maxn], X[maxn*maxn], Y[maxn*maxn]; int n, m, par[maxn*maxn], par2[maxn*maxn]; char str[maxn]; int dx[8] = { 0, 1, 0, -1, 1, 1, -1, -1 }; int dy[8] = { 1, 0, -1, 0, 1, -1, 1, -1 }; struct node{ int x, y; }s[maxn]; void Init(){ for (int i = 0; i <= n*m; i++){ par[i] = i; par2[i] = i; } } int ID(int i, int j) { return i*m + j; } int Find(int x) { return x == par[x] ? x : par[x] = Find(par[x]); } int Find2(int x){ return x == par2[x] ? x : par2[x] = Find2(par2[x]); } void Union(int u, int v) { u = Find(u); v = Find(v); if (u%m<v%m) par[v] = u;//维护最左列 else par[u] = v; } void Union2(int u, int v) { u = Find2(u); v = Find2(v); if (u%m>v%m) par2[v] = u; //维护最右列 else par2[u] = v; } int main() { int i, j, T; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); Init(); for (i = 0; i<n; i++) { scanf("%s", str); for (j = 0; j<m; j++) mp[i][j] = (str[j] - '0'); } for (i = 0; i<n; i++) { for (j = 0; j<m; j++) { if (mp[i][j] == 1) { for (int k = 0; k<8; k++) { int x = i + dx[k], y = j + dy[k]; if (x<0 || x >= n || y<0 || y >= m || mp[x][y] == 0) continue; Union(ID(i, j), ID(x, y)); Union2(ID(i, j), ID(x, y)); } } } } for (i = 0; i<n; i++) { for (j = 0; j<m; j++) Find(ID(i, j)); Find2(ID(i, j)); } //??? int q; scanf("%d", &q); for (i = 1; i <= q; i++) { scanf("%d%d", &X[i], &Y[i]); } for (i = 1; i <= q; i++) { mp[X[i]][Y[i]] = 1; for (int k = 0; k<8; k++) { int x = X[i] + dx[k], y = Y[i] + dy[k]; if (x<0 || x >= n || y<0 || y >= m || mp[x][y] == 0) continue; Union(ID(X[i], Y[i]), ID(x, y)); Union2(ID(X[i], Y[i]), ID(x, y)); } int t = Find(ID(X[i], Y[i])), d = Find2(ID(X[i], Y[i])); if (t%m == 0 && d%m == m - 1) break; } if (i <= q) printf("%d\n", i); else puts("-1"); } return 0; }