DPL_2_A:Traveling Salesman Problem

問題

http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DPL_2_A&lang=jp

巡回セールスマン問題。有向グラフ G(V, E) 上のある頂点から出発して、出発点に戻る閉路の最短距離を求めよ。

制約

  • 2 <= |v| <= 15
  • 0 <= d_i <= 1000

考え方

bitDPである。頂点集合を S として、右から数えて i 番目のビットが1立っているときはその頂点 i を訪問済み。0 のときは未訪問として状態を管理する。もう一つの状態は、現在どこにいるか?という現在位置の状態である。これを v とする。

dp の遷移は、現在の頂点 v から未訪問の頂点 u への遷移を考えれば良い。求める解は k を出発点として dp[(1<<v)-1][k] の最小値である。

       public void solve(int testNumber, InputReader in, PrintWriter out) {

            int v = in.nextInt(), e = in.nextInt();
            int[][] mat = new int[v][v];
            for (int i = 0; i < v; i++) {
                Arrays.fill(mat[i], -1);
            }

            for (int i = 0; i < e; i++) {
                int s = in.nextInt(), t = in.nextInt(), d = in.nextInt();
                mat[s][t] = d;
            }

            int[][] dp = new int[1 << v][v];

            dp = new int[1 << v][v];
            for (int i = 0; i < 1 << v; i++) {
                Arrays.fill(dp[i], INF);
            }
            dp[0][0] = 0;

            for (int s = 0; s < 1<<v; s++) {
                for (int now = 0; now < v; now++) {
                    for (int to = 0; to < v; to++) {
                        if ((s >> to & 1) == 0 && mat[now][to] != -1) {
                            dp[s|1<<to][to] = Math.min(dp[s|1<<to][to], dp[s][now] + mat[now][to]);
                        }
                    }
                }
            }
            out.println(dp[(1<<v)-1][0] == INF ? -1 : dp[(1<<v)-1][0]);
        }

スタート地点を 0 に絞ってbitDPしても通ったのだが、[0, v-1] のすべての k に対してbitDPを求めなくても 0 からだけの値で問題ないのか??
ある頂点から始めて、すべての頂点を1回ずつ訪れることが可能である時、[0, n-1] の頂点の閉路になっているので、どの頂点から始めても同じである。ということであった、

ポイント

頂点集合をビットで管理する以外は通常のナップザックDPと同じである。実際、DP遷移はDAGになっている。