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
|
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAXN = 103;
const int MAX_NODES = 2e4 + 3;
const int MAX_EDGES = 2e5 + 3;
struct Edge {
int to, rest;
} edges[MAX_EDGES];
vector<int> adj[MAX_NODES];
int n, m, a, b, nm, source, sink, edge_count;
int dep[MAX_NODES], depc[MAX_NODES], last[MAX_NODES];
void init() {
edge_count = 0, nm = n * m;
source = 0, sink = nm * 2 + 1;
for (int i = 0; i <= sink; ++i) adj[i].clear();
}
void add_edge(int u, int v, int cap) {
// cerr << u << " -> " << v << " : " << cap << "\n";
edges[edge_count] = {v, cap};
adj[u].push_back(edge_count++);
edges[edge_count] = {u, 0};
adj[v].push_back(edge_count++);
}
int dfs(int u, int flow) {
if (u == sink || !flow) return flow;
int v, e, temp, res = 0;
for (int &i = last[u]; i < (int)adj[u].size(); ++i) {
e = adj[u][i], v = edges[e].to;
if (!edges[e].rest || dep[v] != dep[u] - 1) continue;
temp = dfs(v, min(flow, edges[e].rest));
res += temp, flow -= temp;
edges[e].rest -= temp, edges[e ^ 1].rest += temp;
if (!flow || !dep[source]) return res;
}
last[u] = 0;
if (!--depc[dep[u]]) dep[source] = sink + 1;
++depc[++dep[u]];
return res;
}
int max_flow() {
size_t sz = sizeof(int) * (sink + 1);
memset(dep, 0, sz);
memset(depc, 0, sz);
memset(last, 0, sz);
static queue<int> q;
dep[sink] = 1, q.push(sink);
while (!q.empty()) {
int u = q.front();
q.pop();
++depc[dep[u]];
for (int e : adj[u]) {
int v = edges[e].to;
if (dep[v]) continue;
dep[v] = dep[u] + 1;
q.push(v);
}
}
int res = 0;
while (dep[source] <= sink) res += dfs(source, INT_MAX);
return res;
}
char maze[MAXN][MAXN];
inline int idx(int i, int j, int dense) {
return (i - 1) * m + j + (dense ? nm : 0);
}
inline bool valid(int i, int j) {
return i >= 1 && i <= n && j >= 1 && j <= m && maze[i][j] == '0';
}
void solve() {
cin >> n >> m >> a >> b;
init();
for (int i = 1; i <= n; ++i) cin >> (maze[i] + 1);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
if (maze[i][j] == '1') continue;
add_edge(idx(i, j, 0), idx(i, j, 1), 1);
add_edge(idx(i, j, 1), idx(i, j, 0), 1);
static const int dx[] = {0, 1, 0, -1};
static const int dy[] = {1, 0, -1, 0};
for (int d = 0; d < 4; ++d) {
int i_ = i + dx[d], j_ = j + dy[d];
if (!valid(i_, j_)) continue;
add_edge(idx(i, j, d & 1), idx(i_, j_, d & 1), 1);
}
}
}
for (int i = 0, x; i < a; ++i) {
cin >> x;
if (maze[1][x] == '0') add_edge(source, idx(1, x, 1), 1);
}
for (int i = 0, x; i < b; ++i) {
cin >> x;
if (maze[n][x] == '0') add_edge(idx(n, x, 1), sink, 1);
}
cout << (max_flow() == a ? "Yes\n" : "No\n");
}
int main(int argc, char *argv[]) {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int o_o;
for (cin >> o_o; o_o; --o_o) solve();
return 0;
}
|