A Matrix maze is known as a Matrix maze. It is filled with electricity at the beginning, and requires that the given point be traversed. Each movement consumes 1, several batteries in the Maze can be fully charged (each battery can only be used once), find the minimum original power */first abstract the start point, end point, rechargeable battery, and build their shortest path, the original power is enumerated in two parts to convert to the State DP problem of the Hamilton loop. In this way, we can use two different edges to represent the source image without a rechargeable battery. (In the new figure, if you move one edge to a rechargeable battery, you must use this rechargeable battery, BFS practices (421 ms) [cpp] # include <cstdio> # include <cstring> # include <queue> using namespace std; struct Edge {int v, next;} edge [2000]; int head [300], cnt, ids, fin; int n, m; char map [20] [20]; int id [20] [20]; int c [20] [2]; int dis [20] [20]; struct Node {int s, d ;}; void init () {memset (head,-1, sizeof (head); memset (id,-1, size Of (id); memset (dis,-1, sizeof (dis); cnt = 0, ids = 1, fin = 0;} void addedge (int u, int v) {edge [cnt]. v = v; edge [cnt]. next = head [u]; head [u] = cnt ++;} void bfs (int s) {int I, j, u, v; struct Node tem, tem1; queue <struct Node> q; bool OK [400]; memset (OK, 0, sizeof (OK); tem. s = s, tem. d = 0; q. push (tem); OK [s] = 1; while (! Q. empty () {tem = q. front (); q. pop (); u = tem. s; if (id [u/m] [u % m]! =-1) dis [id [s/m] [s % m] [id [u/m] [u % m] = tem. d; for (I = head [u]; I! =-1; I = edge [I]. next) {v = edge [I]. v; if (OK [v]) continue; OK [v] = 1; tem1.s = v; tem1.d = tem. d + 1; q. push (tem1) ;}} int dp [1 <16] [16]; bool solve (int mid) {int I, j, k; memset (dp, -1, sizeof (dp); dp [1] [0] = mid; for (I = 0; I <(1 <ids); I ++) for (j = 0; j <ids; j ++) {if (I & (1 <j) = 0) | dp [I] [j] =-1) continue; if (I & fin) = fin) return 1; for (k = 0; k <ids; k ++) {if (I & (1 <k) continue; if (dis [k] [j] =-1) continue; if (dp [I] [j]> = dis [k] [J]) {if (dp [I | (1 <k)] [k] =-1 | dp [I | (1 <k)] [k] <dp [I] [j]-dis [k] [j]) dp [I | (1 <k)] [k] = dp [I] [j]-dis [k] [j]; if (map [c [k] [0] [c [k] [1] = 'G') dp [I | (1 <k)] [k] = mid ;}}return 0 ;}int main () {int I, j, k; while (scanf ("% d", & n, & m) & n! = 0 & m! = 0) {init (); for (I = 0; I <n; I ++) scanf ("% s", map [I]); for (I = 0; I <n; I ++) for (j = 0; j <m; j ++) {if (map [I] [j] = 'D') continue; if (map [I] [j] = 'F ') {c [0] [0] = I; c [0] [1] = j; id [I] [j] = 0 ;} else if (map [I] [j] = 'G') {c [ids] [0] = I; c [ids] [1] = j; id [I] [j] = ids ++;} else if (map [I] [j] = 'y') {c [ids] [0] = I; c [ids] [1] = j; id [I] [j] = ids ++; fin | = (1 <(ids-1 ));} if (I-1> = 0 & map [I-1] [j]! = 'D') addedge (I * m + j, (I-1) * m + j ); if (I + 1 <n & map [I + 1] [j]! = 'D') addedge (I * m + j, (I + 1) * m + j); if (J-1> = 0 & map [I] [J-1]! = 'D') addedge (I * m + j, I * m + J-1); if (j + 1 <m & map [I] [j + 1]! = 'D') addedge (I * m + j, I * m + j + 1);}/* for (I = 0; I <ids; I ++) {for (j = 0; j <ids; j ++) printf ("% d", dis [I] [j]); puts ("");} puts (""); */for (I = 0; I <ids; I ++) bfs (c [I] [0] * m + c [I] [1]); int l = 0, r = n * m * (ids-1), mid, ans =-1; while (l <= r) {int mid = (l + r)> 1; if (solve (mid) {ans = mid; r = mid-1;} else l = mid + 1;} printf ("% d \ n", ans);} return 0;} DFS practice (31 ms in use) [cpp] # include <cstdio> # include <cstring> # include <queue> using names Pace std; struct Edge {int v, next;} edge [2000]; int head [300], cnt, ids, fin, mid; int n, m; char map [20] [20]; int id [20] [20]; int c [20] [2]; int dis [20] [20]; struct Node {int s, d ;}; void init () {memset (head,-1, sizeof (head); memset (id,-1, sizeof (id); memset (dis,-1, sizeof (dis); cnt = 0, ids = 1, fin = 0;} void addedge (int u, int v) {edge [cnt]. v = v; edge [cnt]. next = head [u]; head [u] = cnt ++;} void bfs (int s) {int I, j, u, v; struct Node tem, tem1; queue <struct Node> q; bool OK [400]; memset (OK, 0, sizeof (OK )); tem. s = s, tem. d = 0; q. push (tem); OK [s] = 1; while (! Q. empty () {tem = q. front (); q. pop (); u = tem. s; if (id [u/m] [u % m]! =-1) dis [id [s/m] [s % m] [id [u/m] [u % m] = tem. d; for (I = head [u]; I! =-1; I = edge [I]. next) {v = edge [I]. v; if (OK [v]) continue; OK [v] = 1; tem1.s = v; tem1.d = tem. d + 1; q. push (tem1) ;}} int has [20]; int dfs (int pos, int len, int sta) {if (sta & fin) = fin) return 1; for (int I = 0; I <ids; I ++) {if (has [I] | dis [pos] [I] =-1) continue; if (len> = dis [pos] [I]) {if (map [c [I] [0] [c [I] [1] = 'G') {has [I] = 1; if (dfs (I, mid, sta | (1 <I) return 1; has [I] = 0;} else {has [I] = 1; if (dfs (I, len-dis [pos] [I], sta | (1 <I) return 1; has [I] = 0 ;}}return 0 ;}int main () {int I, j, k; while (scanf ("% d", & n, & m) & n! = 0 & m! = 0) {init (); for (I = 0; I <n; I ++) scanf ("% s", map [I]); for (I = 0; I <n; I ++) for (j = 0; j <m; j ++) {if (map [I] [j] = 'D') continue; if (map [I] [j] = 'F ') {c [0] [0] = I; c [0] [1] = j; id [I] [j] = 0 ;} else if (map [I] [j] = 'G') {c [ids] [0] = I; c [ids] [1] = j; id [I] [j] = ids ++;} else if (map [I] [j] = 'y') {c [ids] [0] = I; c [ids] [1] = j; id [I] [j] = ids ++; fin | = (1 <(ids-1 ));} if (I-1> = 0 & map [I-1] [j]! = 'D') addedge (I * m + j, (I-1) * m + j ); if (I + 1 <n & map [I + 1] [j]! = 'D') addedge (I * m + j, (I + 1) * m + j); if (J-1> = 0 & map [I] [J-1]! = 'D') addedge (I * m + j, I * m + J-1); if (j + 1 <m & map [I] [j + 1]! = 'D') addedge (I * m + j, I * m + j + 1);} for (I = 0; I <ids; I ++) bfs (c [I] [0] * m + c [I] [1]); int flag = 1; for (I = 1; I <ids; I ++) {if (map [c [I] [0] [c [I] [1] = 'y ') if (dis [0] [I] =-1) {flag = 0; break;} int ans =-1; if (flag) {int l = 0, r = n * m * (ids-1); while (l <= r) {mid = (l + r)> 1; memset (has, 0, sizeof (has); has [0] = 1; www.2cto.com if (dfs (0, mid, 1) {ans = mid; r = mid-1 ;} else l = mid + 1 ;}} printf ("% d \ n", ans);} return 0 ;}