1. 程式人生 > >[BZOJ 4423] Bytehattan 平面圖與對偶圖

[BZOJ 4423] Bytehattan 平面圖與對偶圖

class urn getch getc union gist 一個點 span true

題意

  給定一個 $n \times n$ 的點陣, 形成一個網格圖.

  最初的時候四連通.

  $m$ 次操作, 每次刪去一條邊 $(u, v)$ , 問 $u$ 和 $v$ 是否仍然連通.

  $2 \le n \le 1500, 1 \le m \le 2n(n - 1)$ .

分析

  將平面圖轉化為它的對偶圖.

  每次相當於將兩個平面區域合並.

  對於刪去一條邊, 若與它相鄰的兩個區域連通, 那麽操作後兩個點中有一個點被區域包圍, 一個點被隔在了外面, 所以不連通, 反之仍然連通.

實現

 1 #include <cstdio>
 2 #include <cstring>
 3
#include <cstdlib> 4 #include <cctype> 5 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 6 inline int rd(void) { 7 int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == -) f = -1; 8 int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-
0; return x*f; 9 } 10 inline char rdc(void) { char c = getchar(); while (!isalpha(c)) c = getchar(); return c; } 11 12 const int N = 2500000; 13 14 int n, m, f[N]; 15 inline int id(int x, int y) { 16 bool Legal = (1 <= x && x < n && 1 <= y && y < n); 17 return
Legal ? (x-1)*(n-1)+y : 0; 18 } 19 inline int Find(int x) { return f[x] == x ? x : f[x] = Find(f[x]); } 20 inline bool Union(int x, int y) { 21 int fx = Find(x); 22 int fy = Find(y); 23 bool ret = (fx != fy); 24 return f[fx] = fy, ret; 25 } 26 27 int main(void) { 28 #ifndef ONLINE_JUDGE 29 freopen("bzoj4423.in", "r", stdin); 30 #endif 31 32 n = rd(), m = rd(); 33 F(i, 0, (n-1)*(n-1)) f[i] = i; 34 35 bool Last = true; 36 F(i, 1, m) { 37 int a = rd(), b = rd(); char c = rdc(); 38 int _a = rd(), _b = rd(); char _c = rdc(); 39 if (!Last) a = _a, b = _b, c = _c; 40 if (c == N) 41 Last = Union(id(a, b), id(a-1, b)); 42 else Last = Union(id(a, b), id(a, b-1)); 43 puts(Last ? "TAK" : "NIE"); 44 } 45 46 return 0; 47 }

  

[BZOJ 4423] Bytehattan 平面圖與對偶圖