Question link:
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 4568
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:
# 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, "/Stack: 1024000000,1024000000") using names Pace 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 from other treasures to the current treasure bool vis [maxn] [maxn]; bool isbor (int x, int y) // determines whether it is a boundary {If (x = 0 | x = n-1 | Y = 0 | Y = m-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 ;}