質問が意図される:n行m列の行列に、数字は(すべての価格を支払うために時間が経過していることに留意)後の行列のコストを表し、行列いくつかの宝物があり、行列ハンターは、すべての宝物を完成取るために任意の境界から行くことができますこれは、任意の境界から出てきました。
解決法:宝13以下の数を確認し、なければなりません、TSPを考えるのは簡単でなければなりません。したがって、我々は最短治療+ DP圧縮された状態のソリューションを使用しています。Sと宝物まず、この全体マップへのすべての事前の宝最短地点のは、準備DPの価格に従うことで、その後、圧力DP、DPの設計DPステータス[S] [今]代表者を好きに始めたとの点セットに行ってきましたです今今宝の最小点で、検索のメモリを転送することができます。
コードの詳細を参照してください、理解して非常に良いことがあります:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 CONSTの INT N = 210 。 const int型 INF = 0x3f3f3f3f 。 CONSTの INT DX [] = { - 1、0、1、0 }。 const int型 DY [] = { 0、1、0、 - 1 }。 INTの N、M、K、[N] [N]、DP [ 1 << 15 ] [ 15 ]、ES [N]、PX [N]、PY [N]。 構造体DAT { int型、D、X、Y。 BOOL 演算子 <(CONST DAT&RHS)のconst { 戻り D> rhs.d。 } }。 PRIORITY_QUEUE <DAT> Q; INT DIS [ 15 ] [N] [N]。 BOOL VIS [N] [N]。 ボイドダイクストラ(int型K){ memsetの(DIS [k]は、0x3fを、はsizeof (DIS [K]))。 memsetの(VIS、0、はsizeof (VIS))。 q.push((DAT){ 0 、PX [K]、PY [K]})。 DIS [K] [PX [K] [PY [K] = 0 ; しばらく(!q.empty()){ DAT U = q.top()。q.pop(); もし(VIS [UX] [UY])続けます。 VIS [UX] [UY] = 1 。 以下のために(int型 i = 0 ; iは< 4 ; I ++ ){ int型 TX = u.x + DX [i]は、TY = u.y + DYの[I]。 もし(TX < 1 || TX> N || TY < 1 || TY> M || [TX] [TY] == - 1)続けます。 もし(DIS [K] [TX] [TY]> DIS [K] [UX] [UY] + [TX] [TY]){ DIS [K] [TX] [TY]= DIS [K] [UX] [UY] + [TX] [TY]。 q.push((DAT){DIS [K] [TX] [TY]、TX、TY})。 } } } } int型 lowbit(INT X){ int型 RET = 0。用(; X; X - = X&-x)RET ++。リターンRET; } INT DFS(INT今、INT X){ 場合(!DP [今] [X] = - 1)戻りDP [今] [X]。 もし(lowbit(今)== 1)戻り ES [X] + [PX [X] [PYの[X]]。 DP [今] [X] = INF。 用(int型 i = 1 ; iが= Kを<; I ++の) 場合(!(I = X)&&(現・(1 << I- 1 ))){ int型 TMP = DFS(今^(1 << X- 1)、I)+ DIS [I] [PX [X] [PYの[X]]。 DP [今] [X] = 分(DP [今] [x]は、TMP)。 } 戻り[今] DPを[X]。 } int型のmain() { int型の T。CIN >> T; 一方、(T-- ){ scanf関数(" %d個の%のD "、&N、&M)。 以下のための(intです i = 1 ; iが<= N; I ++)のための(INT J = 1 ; J <= Mであり、j ++)のscanf(" %dの"、および[I] [J])。 scanf関数(" %のD "、&K)。 以下のために(int型私= 1 ; iが= Kを<; Iは++ ){ scanf関数(" %D%dの"、&PX [i]は、&PY [I])。 PX [I] ++; PY [I] ++ ; ダイクストラ(I); ES [I] = INF。 以下のための(int型 J =1 ; J <= N; J ++)ES [I] =分(ES [i]は、分(DIS [I] [J] [ 1 ]、DIS [I] [J] [M]))。 用(INT J = 1 ; J <= Mであり、j ++)ES [I] =分(ES [i]は、分(DIS [I] [ 1 ] [j]は、DIS [I] [N] [J]) ); } のmemset(DP、 - 1、はsizeof (DP))。 int型 ANS = INF。 以下のために(int型 i = 1 ; iは= Kを<; iは++)ANS =分(ANS、DFS((1 << k)を- 1、I)+ ES [I])。 もし(ANS == INF)のprintf(" -1 "); 他のprintf(" %Dを\ n " 、ANS)。 } 戻り 0 。 }