The main topic: there is a n*m grid, the grid above K places have stone, now requires from the upper left corner, traverse all the stone place, and then go back to the upper left corner, ask the shortest distance is how much
Solution: Because the total number of stones is less than or equal to 10, it can be compressed
Set Dp[i][j][state] in (i,j) position, traverse the state of the stone, the minimum distance to go, directly BFS can
#include <cstdio>#include <cstring>#include <algorithm>#include <map>#include <queue>using namespace STD;#define N -#define S (1<<11)#define INF 0x3f3f3f3fstructNode {intX, Y, state, step;} Start map<int, int>MintN, M, Stone_num;intDp[n][n][s], g[n][n];intdir[4][2] = {{-1,0}, {1,0}, {0, -1}, {0,1}};voidInit () {m.clear (); Stone_num =0; for(inti =0; I < n; i++) for(intj =0; J < M; J + +) {scanf("%d", &g[i][j]);if(G[i][j]) M[i * m + j] = stone_num++; }memset(DP,0,sizeof(DP));}intBFS () { queue<Node>Q Start.x =0; Start.y =0;if(g[0][0]) Start.state = (1<< m[0]);ElseStart.state =0; Start.step =0; Q.push (start); while(!q.empty ()) {Node T = Q.front (); Q.pop ();intx = t.x, y = t.y;if(x = =0&& y = =0&& T.state = = (1<< stone_num)-1) { Break; } for(inti =0; I <4; i++) {intxx = x + dir[i][0];intyy = y + dir[i][1];intstate = T.state;intStep = T.step;if(XX <0|| yy <0|| XX >= N | | YY >= m)Continue;if(G[xx][yy]) state |= (1<< m[xx * M + yy]);if(Dp[xx][yy][state])Continue; Dp[xx][yy][state] = step +1; Node tt; Tt.x = XX; Tt.y = yy; Tt.state = State; Tt.step = T.step +1; Q.push (TT); } }returndp[0][0][(1<< stone_num)-1];}intMain () { while(scanf("%d%d", &n, &m)! = EOF) {init ();if(Stone_num = =0)printf("0\n");Else printf("%d\n", BFS ()); }return 0;}
Above is I complicate, in fact, only state compression, just to calculate the transfer of each state can be, do not need a walk ...
#include <cstdio>#include <cstring>#include <cstdlib>#include <queue>using namespace Std;#define S (1 <<)#define N#define INF 0x3f3f3f3fstruct Stone {int x,y;} Stone[n];struct Node {int State,POS;} StartintNm;intDp[s][n], cnt;void init () {int x; CNT =1; stone[0].x=0; stone[0].y=0; for(inti =0; I < n; i++) for(intj =0; J <m; J + +) {scanf ("%d", &x);if(x) {stone[cnt].x= i; stone[cnt++].y= J; } }}intDisintIintj) {return ABS(Stone[i].x-STONE[J].x) +ABS(Stone[i].y-STONE[J].y);} void Solve () {memset (DP,0x3f, sizeof (DP)); Queue<node>Q; Start. State=1; Start.POS=0;Q.Push(start); dp[1][0] =0; while(!Q. empty ()) {Node T =Q. Front ();Q.Pop();int State= T. State;int POS= T.POS; for(inti =1; I < CNT; i++) {if(! ( State& (1<< i)) {if(( State| (1<< i) = = (1<< CNT)-1) {dp[ State| (1<< i)][i] = min (dp[ State| (1<< i)][i], dp[ State][POS] + DIS (POS, i) + DIS (0, i)); }Else{if(dp[ State| (1<< i)][i] > dp[ State][POS] + DIS (POS, i)) {dp[ State| (1<< i)][i] = dp[ State][POS] + DIS (POS, i); Node tt; Tt. State= State| (1<< i); Tt.POS= i;Q.Push(TT); } } } } }intans = INF; for(inti =1; I < CNT; i++) ans = min (ans, dp[(1<< CNT)-1][i]);printf("%d\ n", ans);}intMain () { while(SCANF ("%d%d", &n, &m) = EOF) {init ();if(CNT = =1)printf("0\n");ElseSolve (); }return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
HDU-5067 Harry and Dig machine (BFS + state compression)