Network Flow dinic Algorithm
The wolf is the source point, and the goat is the sink point.
Connect each source point to a large source point with an infinite capacity.
Connect each sink point to a large sink point with an infinite capacity.
The maximum flow = Minimum Cut = answer.
# Include <iostream> # include <cstdio> # include <cstring> # include <cstdio> # include <queue> # include <vector> using namespace STD; const int maxint = 1000001; # define maxn 40008int S, T; struct edgee {int from, to, Cap, flow ;}; vector <edgee> edges; vector <int> G [maxn]; bool vis [maxn]; int Dist [maxn]; int cur [maxn]; void add (int from, int to, int cap) {edges. push_back (edgee) {from, to, Cap, 0}); edges. push_back (edgee) {to, from, Cap, 0 }); Int K = edges. size (); G [from]. push_back (K-2); // the odd number is positive arc G [to]. push_back (k-1);} int max (int A, int B) {return A> B? A: B;} int min (int A, int B) {return a <B? A: B;} bool BFS () {memset (VIS, 0, sizeof (VIS); queue <int> q; Dist [s] = 0; vis [s] = 1; q. push (s); While (! Q. empty () {int u = Q. front (); q. pop (); int SZ = G [u]. size (); For (INT I = 0; I <SZ; I ++) {edgee & E = edges [G [u] [I]; If (! Vis [E. to] & E. cap> E. flow) {vis [E. to] = 1; Dist [E. to] = DIST [u] + 1; q. push (E. to) ;}}} return vis [T];} int DFS (int u, int low) {If (u = T | low = 0) return low; int flow = 0, SZ = G [u]. size (), D; // & for (Int & I = cur [u]; I <SZ; I ++) // The last side being considered (efficiency critical) {edgee & E = edges [G [u] [I]; if (Dist [u] + 1 = DIST [E. to] & (D = DFS (E. to, min (E. cap-e.flow, low)> 0) {e. flow + = D; edges [G [u] [I] ^ 1]. flow-= D; flow + = D; low-= D; If (Low = 0) break;} return flo W;} int dinic () {int flow = 0; while (BFS () {memset (cur, 0, sizeof (cur); flow + = DFS (S, maxint);} return flow;} int main () {int I, j; int flag = 1; int n, m; while (~ Scanf ("% d", & N, & M) {edges. clear (); for (I = 0; I <maxn; I ++) g [I]. clear (); s = 40002, t = 40003; for (I = 0; I <n; I ++) {int K; For (j = 0; j <m; j ++) {scanf ("% d", & K); If (k = 0) {If (J! M-1) add (I * m + J, I * m + J +);} else {If (k = 2) {If (J! M-1) {Add (I * m + J, I * m + J + 10001);} Add (S, I * m + J );} elseif (k = 1) {If (J! M-1) {Add (I * m + J, I * m + J + 10001);} Add (I * m + J, T );}}}} for (j = 0; j <m; j ++) for (I = 0; I <n-1; I ++) {Add (I) * m + J, (I + 1) * m + J, 1);} int temp = dinic (); printf ("case % d: \ n % d \ n", flag ++, temp);} return 0 ;}