質問の意味:すべての点の開始点を選択した後無向グラフが与えられると、各点が2倍以上にすることはできませんが、少なくとも一度通って最短経路を求めました。
解決策:この問題は倍以上の各点を通っていないことに注意してください、と異なるTSPの一般的な問題。しかし、この問題は非常に複雑で、私たちは、バイナリ圧縮によって表現され、元の状態になってきたことはなかった、この時間は十分ではありません、我々は0、1、2回を通じて表現しなければなりません。どう思いますか?はい、それは三元表現することができ、TSP及び他の同様の問題です。DP [S]は、[X] Sは現在のX点距離のターゲットの完全なパス長された状態への通路を表します。いつものようにdpができます。
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 const int型 M = 10 * 10 。 const int型 INF = 0x3f3f3f3f 。 INTのN、M。 int型の CNT、ヘッド[M << 1 ]、NXT [M << 1 ]乃至[M << 1 ]、LEN [M << 1 ]。 ボイド add_edge(int型のx、int型の Y、int型Z){ NXT [ ++ CNT] =頭部[X]。[CNT] = Yであり; LEN [CNT] = Z; ヘッド[X] = CNT。 } INT INC(INT S、INTX){ int型、P = 1。用(; X> 1 ; x--)、P * = 3 。 返す S + Pを、 } INT GET(INT S、INT X){ int型、T = 1 。 一方、(T <= N){ もし(T == x)をリターン S%3 。 S / = 3。トン++ ; } } ブールチェック(int型S){ int型、T = 1 。 一方、(T <= N){ 場合(S%3 == 0)戻り 0 ; S / = 3。トン++ ; } リターン 1 。 } INT DP [ 200000 ] [ 12 ]。 INT DFS(INT S、INT X){ 場合(チェック(S))戻り 0 ; もし(!DP [S] [X] = - 1)戻りDP [S] [X]。 int型 RET = INF。 にとって(int型 I =ヘッド[X]; I; I = NXT [I]){ int型、Y = 乃至[I]。 場合(取得(S、y)は< 2 RET =分)(RET、DFS(INC(S、y)は、Y)+ LEN [I])。 } 戻り DPを[S] [X] = RET。 } int型のmain() { 一方(のscanf(" %d個の%のD "、&N、&M)== 2 ){ CNT = 1、memsetの(頭、0、はsizeof (ヘッド))。 以下のために(int型 I = 1 ; I <= M; iは++ ){ INT X、Y、Z。scanf関数(" %D%D%D "、およびX&Y、およびZ)。 add_edge(X、Y、Z)。 add_edge(X、Y、Z)。 } のmemset(DP、 - 1、はsizeof (DP))。 int型 ANS = INF。 以下のために(int型 I = 1 ANS =分(ANS、DFS(INC(iは++; = n iは<)0 、i)は、I))。 もし(ANS == INF)プット(" -1 "); 他のprintf(" %d個の\ nを" 、ANS)。 } 戻り 0 。 }