Hdu_3681
Since y and G are less than 15, the shortest circuit between F, y, and g can be processed in advance and then converted into the TSP problem.
# Include <stdio. h> # Include < String . H> # Include <Algorithm> # Include <Queue> # Define Maxd 20 Int N, m, DIS [maxd] [maxd], G [maxd] [maxd], Mark, Y, G, Sx, Sy, vis [maxd] [maxd]; Int DX [] = {-1 , 1 , 0 , 0 }, Dy [] = { 0 , 0 ,- 1 , 1 }; Char B [maxd] [maxd]; Int F [ 1 < 15 | 10 ] [Maxd]; Void Init (){ Int I, J; y = 1 ; For (I = 1 ; I <= N; I ++ ) {Scanf ( " % S " , B [I] + 1 ); For (J = 1 ; J <= m; j ++ ){ If (B [I] [J] = ' F ' ) G [I] [J] = 0 , SX = I, Sy = J; Else If (B [I] [J] = ' S ' ) G [I] [J] =- 1 ; Else If (B [I] [J] = ' Y ' ) G [I] [J] = y ++ ; Else If (B [I] [J] = ' D ' ) G [I] [J] =- 2 ;} Mark = ( 1 <Y )-2 , G = Y; For (I = 1 ; I <= N; I ++ ) For (J = 1 ; J <= m; j ++ ) If (B [I] [J] = ' G ' ) G [I] [J] = g ++ ;} Inline Int Inside (Int X, Int Y ){ Return X> = 1 & X <= N & Y> = 1 & Y <= M ;} Void DFS ( Int X, Int Y ){ Int I, NX, NY; vis [x] [Y] = 1 ; For (I = 0 ; I < 4 ; I ++ ) {NX = X + dx [I], NY = Y + Dy [I]; If (Inside (NX, NY )&&! Vis [NX] [NY] & G [NX] [NY]! =- 2 ) DFS (NX, NY );}} Int Check (){ Int I, J; memset (VIS, 0 , Sizeof (VIS); DFS (sx, Sy ); For (I = 1 ; I <= N; I ++ ) For (J = 1 ; J <= m; j ++ ) If (B [I] [J] = ' Y ' &&! Vis [I] [J]) Return 0 ; Return 1 ;} Void BFS ( Int SX, Int Sy ){ Int I, j, X, Y, NX, NY, id = G [SX] [sy]; memset (VIS, - 1 , Sizeof (VIS); STD: queue < Int > Q; vis [SX] [sy] = 0 ; Q. Push (SX * (M + 1 ) + Sy ); While (! Q. Empty () {x = Q. Front ()/(m + 1 ), Y = Q. Front () % (m + 1 ), Q. Pop (); If (G [x] [Y]> = 0 ) Dis [ID] [G [x] [Y] =Vis [x] [Y]; For (I = 0 ; I < 4 ; I ++ ) {NX = X + dx [I], NY = Y + Dy [I]; If (Inside (NX, NY) & Vis [NX] [NY] =- 1 & G [NX] [NY]! =- 2 ) Vis [NX] [NY] = Vis [x] [Y] + 1 , Q. Push (nx * (m + 1 ) +NY );}}} Int DP ( Int Limit ){ Int I, J, K; memset (F, - 1 , Sizeof (F); F [ 1 ] [ 0 ] = Limit; For (I = 1 ; I <( 1 <G); I ++ ) For (J = 0 ; J <G; j ++ ){ If (F [I] [J] =- 1 ) Continue ; If (I & mark) = mark) Return 1 ; For (K = 0 ; K <G; k ++ ) If (I & 1 <K) = 0 & F [I] [J]> = Dis [J] [k]) { If (K> = y) f [I | 1 <K] [k] = Limit; Else F [I | 1 <K] [k] = STD: max (F [I | 1 <K] [K], F [I] [J]-Dis [J] [k]) ;}} Return 0 ;} Void Solve (){ Int I, J; If (Y = 1 ) {Printf ( " 0 \ n " ); Return ;} If (! Check () {printf ( " -1 \ n " ); Return ;} Memset (DIS, 0x3f , Sizeof (DIS )); For (I = 1 ; I <= N; I ++ ) For (J = 1 ; J <= m; j ++ ) If (G [I] [J]> = 0 ) BFS (I, j ); Int Min = 0 , Max = 1000 , Mid; For (;) {Mid = Min + MAX + 1 > 1 ; If (Mid = max) Break ; If (Dp (MID) max = Mid; Else Min = Mid;} printf ( " % D \ n " , Mid );} Int Main (){ While (Scanf (" % D " , & N, & M), N | M) {Init (); solve ();} Return 0 ;}