Title: HDU: 4771 stealing Harry Potter's precious
The N * M matrix is given, which represents N * m rooms. Then each room is vulnerable and sturdy, which are replaced by '.' and. '@' Indicates the start point of dudely.
Dudely wants to steal Harry's treasures. He knows where the treasures are, but his magic can only go through the fragile room. Stupid, he wants to steal all Harry's treasures, and doesn't care how people go out. Ask the shortest number of moves to steal all the treasures. No way to steal all the treasures and output-1.
Solution: the shortest path is required. You can find the shortest distance between each treasure and the shortest distance from the starting point to each treasure, arrange all the paths that can be generated, and maintain the minimum value of the total distance. Note: If you find that there are two treasures in the shortest distance before, or the treasures and the starting point are not reachable, it means that dudely cannot complete all the treasures and can directly output-1, you do not need to judge later.
Code:
# Include <stdio. h> # include <string. h ># include <algorithm> using namespace STD; const int n = 105; const int M = 5; int n, m, Q; char map [N] [N]; int Dist [N] [N]; int ans [m] [m]; // The shortest distance. Int mm; // minimum total distance int vis [m]; const int dir [4] [2] = {0,-1}, {-1, 0 }, {0, 1}, {1, 0 }}; const int INF = 0x6ffffff; struct precious {int X, Y;} precious [m], Q [N * n]; int min (const int X, const int y) {return x <Y? X: Y;} int BFS (const precious begin, const precious end) {memset (Dist, 0, sizeof (DIST); int front, rear; front = 0; rear = 1; Q [Front]. X = begin. x; Q [Front]. y = begin. y; while (front <rear) {If (Q [Front]. X = end. X & Q [Front]. y = end. y) return Dist [Q [Front]. x] [Q [Front]. y]; for (INT I = 0; I <4; I ++) {q [rear]. X = Q [Front]. X + dir [I] [0]; Q [rear]. y = Q [Front]. Y + dir [I] [1]; If (Q [rear]. x <0 | Q [rear]. X> = n | Q [rear]. Y <0 | Q [rear]. y> = m) continue; If (Map [Q [rear]. x] [Q [rear]. y]! = '#'&&! Dist [Q [rear]. x] [Q [rear]. y]) {Dist [Q [rear]. x] [Q [rear]. y] = DIST [Q [Front]. x] [Q [Front]. y] + 1; Rear ++ ;}} front ++ ;}return-1 ;}bool solve () {memset (ANS,-1, sizeof (ANS )); for (INT I = 0; I <= Q; I ++) for (Int J = I + 1; j <= Q; j ++) {ans [I] [J] = ans [J] [I] = BFS (precious [I], precious [J]); if (ANS [I] [J] =-1) return false;} return true;}/* void DFS (int K, int X, int sum) {If (k = q) {mm = min (mm, sum); R Eturn ;}for (INT I = 1; I <= Q; I ++) {If (! Vis [I] & Ans [x] [I]! =-1) {If (sum + ans [x] [I]> = mm) return; vis [I] = 1; DFS (k + 1, I, sum + ans [x] [I]); vis [I] = 0 ;}}*/void DFS () {int s [m]; for (INT I = 1; I <= Q; I ++) s [I-1] = I; sort (S, S + q); int sum = 0; do {sum = ans [0] [s [0]; for (INT I = 0; I <q-1; I ++) sum + = ans [s [I] [s [I + 1]; Mm = min (mm, sum);} while (next_permutation (S, S + q);} int main () {char ch; while (scanf ("% d % C", & N, & M, & Ch ), N | M) {(INT I = 0; I <n; I ++) {for (Int J = 0; j <m; j ++) {scanf ("% C ", & map [I] [J]); If (Map [I] [J] = '@') {precious [0]. X = I; precious [0]. y = J ;}} scanf ("% C", & Ch) ;}scanf ("% d", & Q); For (INT I = 1; I <= Q; I ++) {scanf ("% d", & precious [I]. x, & precious [I]. y); precious [I]. X --; precious [I]. Y --;} If (! Solve () printf ("-1 \ n"); else {mm = inf; memset (VIS, 0, sizeof (VIS); // DFS (0, 0, 0); DFS (); printf ("% d \ n", MM) ;}} return 0 ;}