1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
| #include <cstdio> #include <cctype> #include <cstdarg> #include <cstring> #include <queue> #include <algorithm> const int NMAX = 1035, INF = 0x3f3f3f3f; const int dx[5] = {-1, 0, 1, 0}, dy[5] = {0, -1, 0, 1};
template <typename T> void read(T &value) { T result = T(0); bool sign = false; char word = getchar(); while (!isdigit(word)) sign |= (word == '-'), word = getchar(); while (isdigit(word)) result = result * 10 + T(word - '0'), word = getchar(); value = sign ? -result : result; }
template <typename T, typename... Ts> void read(T &value, Ts &...remain) { read(value); read(remain...); }
struct Edge { int t, w, n; Edge(int _t = 0, int _w = 0, int _n = 0) : t(_t), w(_w), n(_n) {} } edge[NMAX << 3]; int head[NMAX], start[NMAX], depth[NMAX], T, n, m, k, s, t, total; bool broken[35][35];
inline void insert(int u, int v, int w) { edge[++total] = Edge(v, w, head[u]); head[u] = total; }
bool bfs() { memset(depth, 0, sizeof(depth)), memcpy(start, head, sizeof(head)); std::queue<int> q; q.push(s), depth[s] = 1; while (!q.empty()) { int u = q.front(); q.pop(); for (int i = head[u]; i; i = edge[i].n) { int v = edge[i].t; if (edge[i].w && !depth[v]) depth[v] = depth[u] + 1, q.push(v); } } return depth[t]; }
int dfs(int u, int a) { if (u == t || !a) return a; int f, r = 0; for (int &i = start[u]; i; i = edge[i].n) { int v = edge[i].t; if (edge[i].w && depth[v] == depth[u] + 1 && (f = dfs(v, std::min(a, edge[i].w)))) { r += f, a -= f; edge[i].w -= f, edge[i ^ 1].w += f; if (!a) break; } } return r; }
int dinic() { int flow = 0; while (bfs()) flow += dfs(s, INF); return flow; }
void construct() { memset(head, 0, sizeof(head)), memset(broken, 0, sizeof(broken)); read(n, m, k), s = 0, t = n * m + 1, total = 1; for (int i = 1, x, y; i <= k; i++) read(x, y), broken[x][y] = true; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { if (broken[i][j]) continue; int p = (i - 1) * m + j; if ((i + j) & 1) insert(p, t, 1), insert(t, p, 0); else { insert(s, p, 1), insert(p, s, 0); for (int _k = 0; _k < 4; _k++) { int _i = i + dx[_k], _j = j + dy[_k]; if (_i < 1 || _i > n || _j < 1 || _j > m || broken[_i][_j]) continue; int _p = (_i - 1) * m + _j; insert(p, _p, 1), insert(_p, p, 0); } } } }
int main() { read(T); while (T--) { construct(); int flow = dinic(); printf("%s\n", (2 * flow == n * m - k) ? "YES" : "NO"); } return 0; }
|