首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

HDU Victor and World:Floyd + 狀態壓縮 DP 解 TSP

     編輯:關於C++

題目大意

  • n ≤ 17 個城市,m 條雙向路,每條有長度。
  • 從城市 1 出發,遍歷所有城市並返回 1,求最小總路程。

解法:Floyd 預處理 + TSP DP

  1. Floyd-Warshall 算出任意兩點最短距離 dist[i][j]。
  2. 狀態 dp[mask][i]:已訪問集合為 mask(bitmask),當前在城市 i 的最小路程。
     mask 第 k 位 = 1 表示城市 k+1 已訪問。
  3. 初始:dp[1][0] = 0(城市 1 編號 0),其餘 INF。
  4. 轉移:
     for mask from 1 to (1<
      for i in 0..n-1 if (mask & (1<
       for j in 0..n-1 if (!(mask & (1<
        dp[mask | (1<
  5. 答案:min_i dp[(1<。

完整代碼

#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
int dist[18][18];
int dp[1<<17][17];

int main() {
    int n, m;
    while (cin >> n >> m) {
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j)
                dist[i][j] = (i==j?0:INF);
        for (int i = 0; i < m; ++i) {
            int u, v, w; cin >> u >> v >> w; --u; --v;
            dist[u][v] = dist[v][u] = min(dist[u][v], w);
        }
        // Floyd
        for (int k = 0; k < n; ++k)
            for (int i = 0; i < n; ++i)
                for (int j = 0; j < n; ++j)
                    dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
        // DP
        int ALL = 1 << n;
        for (int mask = 0; mask < ALL; ++mask)
            for (int i = 0; i < n; ++i)
                dp[mask][i] = INF;
        dp[1][0] = 0;
        for (int mask = 1; mask < ALL; ++mask) {
            for (int i = 0; i < n; ++i) if (mask & (1<

複雜度

  • Floyd:O(n³),n ≤ 17 微秒級。
  • DP:狀態 2^n × n ≈ 2.2M,轉移 O(n),總 O(n² 2^n) ≈ 38M,C++ 輕鬆通過。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved