我们可以得到一个结论:没有两个机器人走过的路会重叠
所以题目就转变为了能不能让机器人的路径不重叠且每个机器人能到达终点
直接一个点朝他四连通方向的四个点连容量为1的边即可
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef int JQK; int n, m; char ch[105][105]; const int dir[4][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}}; namespace dinic { const int MAXN = 10050; const int MAXM = 100050; const int INF = 1000000050; int Head[MAXN], cur[MAXN], lev[MAXN], to[MAXM << 1], nxt[MAXM << 1], ed = 1; int S, T, MAXP; JQK f[MAXM << 1]; inline void addedge(int u, int v, JQK cap) { to[++ed] = v; nxt[ed] = Head[u]; Head[u] = ed; f[ed] = cap; to[++ed] = u; nxt[ed] = Head[v]; Head[v] = ed; f[ed] = 0; return; } inline bool BFS() { int u; for (int i = 0; i <= MAXP + 1; i++) { lev[i] = -1; } //memset(lev, -1, sizeof(lev)); queue<int>q; lev[S] = 0; q.push(S); while (q.size()) { u = q.front(); q.pop(); for (int i = Head[u]; i; i = nxt[i]) if (f[i] && lev[to[i]] == -1) { lev[to[i]] = lev[u] + 1; q.push(to[i]); /* if (to[i] == T) { return 1; } magic one way optimize */ } } for (int i = 0; i <= MAXP + 1; i++) { cur[i] = Head[i]; } //memcpy(cur, Head, sizeof Head); return lev[T] != -1; } JQK DFS(int u, JQK maxf) { if (u == T || !maxf) { return maxf; } JQK cnt = 0, tem; for (int &i = cur[u]; i; i = nxt[i]) if (f[i] && lev[to[i]] == lev[u] + 1) { tem = DFS(to[i], min(maxf, f[i])); maxf -= tem; f[i] -= tem; f[i ^ 1] += tem; cnt += tem; if (!maxf) { break; } } if (!cnt) { lev[u] = -1; } return cnt; } JQK Dinic() { JQK ans = 0; while (BFS()) { ans += DFS(S, INF); } return ans; } void init(int SS, int TT) { for (int i = 0; i <= MAXP + 1; i++) { Head[i] = 0; } ed = 1; S = SS; T = TT; return; } void work(int aim) { int u, v, c; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (ch[i][j] == '1') { continue; } for (int k = 0; k < 4; k++) { int dx = i + dir[k][0]; int dy = j + dir[k][1]; if (dx >= 1 && dx <= n && dy >= 1 && dy <= m) { if (ch[dx][dy] == '1') { continue; } addedge((i - 1)*m + j, (dx - 1)*m + dy, 1); } } } } int ans = Dinic(); printf(ans == aim ? "Yes " : "No "); } } int main() { int TNT, a, b, x, s, t; scanf("%d", &TNT); while (TNT--) { scanf("%d %d", &n, &m); scanf("%d %d", &a, &b); dinic::MAXP = n * m + 5; s = n * m + 1; t = s + 1; dinic::init(s, t); for (int i = 1; i <= n; i++) { scanf("%s", ch[i] + 1); } for (int i = 1; i <= a; i++) { scanf("%d", &x); dinic::addedge(s, x, 1); } for (int i = 1; i <= b; i++) { scanf("%d", &x); dinic::addedge(x + (n - 1)*m, t, 1); } if (a > b) { printf("No "); continue; } dinic::work(a); } return 0; }