Question:
Give a matrix n * m (n m <= 200), if the square is 0 ~ 9 indicates the cost to pass it, and-1 indicates that it cannot pass.
There are k (k <= 13) pieces of jewelry in the Matrix. Ask to get all the jewelry from any outer border and find the minimum cost of getting out of the matrix.
Solution:
Dij pre-processes the minimum cost of each jewelry to other jewelry, excluding its own cost. Then there is the bare TSP problem, And the status can be compressed to dp.
Dp [I] [j] indicates the minimum cost when the first jewelry is reached and the access status is j.
Dd [I] [j] indicates the cost between jewelry I and jewelry j. Note that the cost of j does not include the cost of I.
For each acquired jewelry status update, the status of the jewelry is not found.
Code:
<SPAN style = "FONT-SIZE: 14px "> # include <iostream> # include <cmath> # include <cstdio> # include <cstdlib> # include <string> # include <cstring> # include <algorithm> # include <vector> # include <map> # include <set> # include <stack> # include <list> # include <queue> # define eps 1e-6 # define INF 0x1f1f1f1f # define PI acos (-1.0) # define ll _ int64 # define lson l, m, (rt <1) # define rson m + 1, r, (rt <1) | 1 // # pragma comment (linker, "/stacks: 1024 1000000,1024000000 ") using namespace std;/* freopen (" data. in "," r ", stdin); freopen (" data. out "," w ", stdout); */struct Node {int id, dis; // Node () {} Node (int x, int y) {id = x, dis = y;} friend bool operator <(const struct Node & a, const struct Node & B) {return. dis> B. dis; // sort by distance from small to facilitate priority queue to find the minimum distance from the current treasure };# define Maxn 220int dd [20] [20]; // The distance between the two treasures: int dir [4] [2] = {-}, {0,-1 }}; int istr [Maxn] [Maxn]; // Indicates the jewelry label int sa [Maxn] [Maxn], cost [20]; // cost [I] indicates the shortest distance from the treasure to the boundary int n, m, k, hash [20], dp [20] [1 <15]; int tmpdis [Maxn * Maxn]; // distance of other treasures from the current treasure bool vis [Maxn] [Maxn]; bool isbor (int x, int y) // whether the boundary is {if (x = 0 | x = n-1 | y = 0 | y = s-1) return true; return false ;} bool iscan (int x, int y) // whether it is inside the matrix {if (x <0 | x> = n | y <0 | y> = m) return false; return true;} void dij (int hh, int cur) // evaluate the memset (tmpdis, INF, sizeof (tmpdis) algorithm )); Memset (vis, false, sizeof (vis); vis [hh/m] [hh % m] = true; priority_queue <Node> myq; tmpdis [hh] = 0; myq. push (Node (hh, 0); while (! Myq. empty () {Node tmp = myq. top (); // locate myq at the least distance from the current treasure. pop (); int tt = tmp. id; int x = tt/m, y = tt % m; if (isbor (x, y) // if it is a boundary, update the boundary cost [cur] = min (cost [cur], tmp. dis); if (istr [x] [y]! =-1) // if it is another jewelry, update the distance between the two jewelry dd [cur] [istr [x] [y] = tmp. dis; for (int I = 0; I <4; I ++) // can walk {int xx = x + dir [I] [0], yy = y + dir [I] [1]; if (! Iscan (xx, yy) | vis [xx] [yy]) continue; if (sa [xx] [yy] =-1) continue; vis [xx] [yy] = true; int temp = xx * m + yy; tmpdis [temp] = min (tmpdis [temp], tmp. dis + sa [xx] [yy]); myq. push (Node (temp, tmpdis [temp]) ;}} int main () {int t, a, B; scanf ("% d", & t ); while (t --) {scanf ("% d", & n, & m); for (int I = 0; I <n; I ++) for (int j = 0; j <m; j ++) scanf ("% d", & sa [I] [j]); scanf ("% d ", & k); memset (istr,-1, sizeof (istr); for (int I = 0; I <k; I ++) {SC Anf ("% d", & a, & B); istr [a] [B] = I; hash [I] = a * m + B; // convert coordinates from two dimensions to one dimension for processing} memset (dd, INF, sizeof (dd); for (int I = 0; I <k; I ++) // obtain the distance from each treasure to other treasure {cost [I] = INF; dd [I] [I] = 0; // The distance between the treasure itself and itself is 0 dij (hash [I], I); // find the shortest distance from I to all the treasures // printf ("I: % d cost: % d \ n ", I, cost [I]);} memset (dp, INF, sizeof (dp); for (int I = 0; I <k; I ++) {// dp [I] [1 <I] includes the cost of I, + cost [I] dp [I] [1 <I] = cost [I] + sa [hash [I]/m] [hash [I] % m]; // printf ("I: % d dp [I] [1 <I]: % d \ n ", I, dp [I] [1 <I]);} int lim = 1 <k; for (int I = 0; I <lim; I ++) {for (int j = 0; j <k; j ++) {if (! (I & (1 <j) // if it does not pass through the j jewelry continue; if (dp [j] [I] = INF) // this status is invalid. continue; for (int p = 0; p <k; p ++) {if (I & (1 <p )) // p is not continue; if (dd [j] [p] = INF) continue; // The final result is p. Based on j-> p, the status dp [p] [I | (1 <p)] After p is updated. = min (dp [p] [I | (1 <p)], dp [j] [I] + dd [j] [p]);} // dp [j] [I] is the obtained status} int ans = INF; for (int I = 0; I <k; I ++) {// printf ("% d \ n", I, dp [I] [lim-1]); ans = min (ans, dp [I] [lim-1] + cost [I]); // going out from the Shortest Path} printf ("% d \ n", ans);} return 0 ;} </SPAN>