There are n pawns on an N * n chessboard. Each time you move a piece up, down, left, or right, the last row, one column, or the Primary and Secondary diagonal lines (therefore, a total of 2n + 2 possible target States) require the minimum number of moves. There are some positions on the board that are obstacles and the pawns cannot go through at any time. The initial position of a piece must not be on the obstacle. Any two pawns cannot reach the same grid at the same time.
[Input file] the first line of the input file move. In contains two integers, N and M, indicating the number of pawns (which is also the length of the Board side) and the number of obstacles. The following n rows, two integers (x, y) in each row, represent the coordinates of the I-th pawn (1 <= X, Y <= N), and the following m rows, each line provides the coordinates of an obstacle. Assume that the n + M coordinates do not overlap. Output file: the output file contains only one integer, indicating the minimum number of moving steps. If there is no solution, output-1. [Example] Move. in5 11 22 43 45 15 31 1move. out6 [limit] 50% of data is satisfied: 2 <= n <= 15, M = 0100% of data is satisfied: 2 <= n <= 50, 0 <= m <= 100
This topic describes the application of the KM algorithm. The first step is to start with all the pieces and calculate the single-source shortest short circuit separately (because the figure is very sparse, you can use the wide search interface. Then, enumerate the end point (by row, column, and two diagonal enumeration), perform a minimum match (using the KM algorithm), and finally obtain a minimum value among all matching values. Accode:
# Include <cstdio> # include <cstdlib> # include <algorithm> # include <string> # include <cstring> const char fi [] = "move. in ", fo [] =" move. out "; const int maxn = 60, size = 0 xFFFF; const int max = 0x3f3f3f, min = ~ Max; const int DX [] = {0, 0, 1,-1}; const int dy [] = {1,-1, 0, 0 }; struct node {int X, Y; node () {} node (int x, int y): x (x), y (y) {}} Q [size + 1], chess [maxn], target [maxn]; bool _ chess [maxn], _ target [maxn]; bool MP [maxn] [maxn], vis [maxn] [maxn]; int lx [maxn], Ly [maxn], DIST [maxn] [maxn] [maxn]; int link [maxn], n, m, F, R, ANS = max; inline int getint () {int res = 0; char TMP; while (! Isdigit (TMP = getchar (); Do res = (RES <3) + (RES <1) + TMP-'0 '; while (isdigit (TMP = getchar (); Return res;} void Init () {freopen (FI, "r", stdin); freopen (FO, "W ", stdout); n = getint (); M = getint (); For (INT I = 0; I <n; ++ I) {int x = getint (), y = getint (); chess [I] = node (X-1, Y-1);} memset (MP, 1, sizeof MP); For (INT I = 0; I <m; ++ I) {int u = getint (), V = getint (); MP [U- 1] [V-1] = 0;} return;} void BFS (INT s) {memset (VIS, 0, sizeof vis ); dist [s] [chess [s]. x] [chess [s]. y] = 0; vis [chess [s]. x] [chess [s]. y] = 1; Q [(r = f = 0) ++] = chess [s]; while (F <r) {node now = Q [f ++]; int x = now. x, Y = now. y; For (Int J = 0; j <4; ++ J) {int u = x + dx [J], V = Y + dy [J]; if (U <0 | u> = n | V <0 | V> = N) continue; If (MP [u] [v] &! Vis [u] [v]) {vis [u] [v] = 1; dist [s] [u] [v] = DIST [s] [x] [Y] + 1; Q [R ++] = node (u, v) ;}}return;} bool find (int I) {_ chess [I] = 1; for (Int J = 0; j <n; ++ J) if (! _ Target [J] & lx [I] + ly [J] = DIST [I] [target [J]. x] [target [J]. y]) {_ target [J] = 1; if (link [J] =-1 | find (link [J]) {link [J] = I; return 1 ;}} return 0 ;}int km () {for (INT I = 0; I <n; ++ I) {lx [I] = max; ly [I] = 0; Link [I] =-1; for (Int J = 0; j <n; ++ J) lx [I] = STD :: min (LX [I], DIST [I] [target [J]. x] [target [J]. y]) ;}for (int K = 0; k <n; ++ K) // here, the cyclic variable must not use I. While (1) {memset (_ chess, 0, sizeof _ chess); memset (_ target, 0, sizeof _ target); If (find (k) break; int max = min; For (INT I = 0; I <n; ++ I) if (_ chess [I]) for (Int J = 0; j <N; ++ J) if (! _ Target [J]) max = STD: max (max, LX [I] + ly [J]-Dist [I] [target [J]. x] [target [J]. y]); For (INT I = 0; I <n; ++ I) {If (_ chess [I]) lx [I]-= max; if (_ target [I]) ly [I] + = max ;}// note that the minimum matching and maximum matching are slightly different. Int ans = 0; For (INT I = 0; I <n; ++ I) ans ++ = DIST [LINK [I] [target [I]. x] [target [I]. y]; return ans;} void work () {memset (Dist, 0x3f, sizeof Dist); For (INT I = 0; I <n; ++ I) BFS (I); // you must use each piece as the starting point to find the shortest path, otherwise it will be wasted. For (INT I = 0; I <n; ++ I) {bool OK = 1; for (Int J = 0; j <n; ++ J) if (! MP [I] [J]) {OK = 0; break;} If (! OK) continue; For (Int J = 0; j <n; ++ J) target [J] = node (I, j); ans = STD: min (ANS, km () ;}for (Int J = 0; j <n; ++ J) {bool OK = 1; for (INT I = 0; I <N; ++ I) if (! MP [I] [J]) {OK = 0; break;} If (! OK) continue; For (INT I = 0; I <n; ++ I) Target [I] = node (I, j); ans = STD: min (ANS, km ();} bool OK = 1; for (INT I = 0; I <n; ++ I) if (! MP [I] [I]) {OK = 0; break;} If (OK) {for (INT I = 0; I <n; ++ I) target [I] = node (I, I); ans = STD: min (ANS, km ();} OK = 1; for (INT I = 0; I <n; ++ I) if (! MP [I] [n-I-1]) {OK = 0; break;} If (OK) {for (INT I = 0; I <n; ++ I) target [I] = node (I, n-I-1); ans = STD: min (ANS, km ();} printf ("% d \ n ", ans <Max? Ans:-1); return;} int main () {Init (); Work (); Return 0 ;}