For an N * m numeric array, 1 indicates the position of the goat, 2 indicates the position of the wolf, 0 indicates nothing, and can pass through. You can build a fence on the four sides of each grid. If there is a fence, the wolf cannot pass through.
Currently, the minimum number of fences is required to prevent the wolf from accessing the sheep.
The model of the question is very simple. A super source point and a super sink point are directly established. The wolf connects to a remote node with an infinite traffic, and the goat connects to a sink node with an infinite traffic, each grid and the four surrounding grids create a side with a traffic of 1. to separate the wolf and goat, the minimum cut is required. The maximum flow is equal to the minimum cut, and the problem is solved successfully.
Summon code:
# Include <iostream> # include <cstdio> # include <cstring> # define maxn 100100 # define INF 99999999 using namespace STD; int to [maxn], C [maxn], first [maxn], next [maxn], n; int d [maxn]; int s, t, n, m, TMP, ANS, CAS = 0; int Q [maxn], bot, top, tag [maxn], can [maxn], tag = 423; void _ Init () {ans = s = 0, t = n * m + 1, n =-1; for (INT I = s; I <= T; I ++) first [I] =-1 ;} void edge (int u, int V, int W) {n ++; To [N] = V, C [N] = W; next [N] = first [u], first [u] = N;} Vo ID _ input () {int cur = 0; For (INT I = 1; I <= N; I ++) for (Int J = 1; j <= m; j ++) {scanf ("% d", & TMP); cur ++; if (I <n) edge (cur, cur + M, 1 ), edge (cur + M, cur, 1); If (j <m) edge (cur, cur + 1, 1), edge (cur + 1, cur, 1 ); if (TMP = 2) edge (S, cur, INF), edge (cur, S, INF); else if (TMP = 1) edge (cur, T, INF), edge (T, cur, INF) ;}} bool BFS () {tag ++; Q [bot = Top = 1] = t, d [T] = 0, tag [T] = tag; while (BOT <= Top) {int cur = Q [bot ++]; for (INT I = first [cur ]; I! =-1; I = next [I]) {If (C [I ^ 1] <= 0 | tag [To [I] = tag) continue; tag [To [I] = tag, d [To [I] = d [cur] + 1, Q [++ top] = to [I]; if (to [I] = s) return true;} return false;} int DFS (INT cur, int num) {If (cur = T) return num; int TMP = num, K; For (INT I = first [cur]; I! =-1; I = next [I]) {If (d [cur]! = D [To [I] + 1 | C [I] <= 0 | tag [To [I]! = Tag | can [To [I] = tag) continue; k = DFS (to [I], min (Num, C [I]); if (k) C [I]-= K, C [I ^ 1] + = K, num-= K; If (num = 0) break ;} if (Num) can [cur] = tag; return TMP-num;} int main () {While (scanf ("% d", & N, & M )! = EOF) {_ Init (); _ input (); While (BFS () ans + = DFS (S, INF); printf ("case % d: \ n % d \ n ", ++ cas, ANS);} return 0 ;}