最短哈密頓路徑 二進位制壓縮思想

2021-10-10 08:36:20 字數 1356 閱讀 4755

給定一張 n 個點的帶權無向圖,點從 0~n-1 標號,求起點 0 到終點 n-1 的最短hamilton路徑。 hamilton路徑的定義是從 0 到 n-1 不重不漏地經過每個點恰好一次。

輸入格式

第一行輸入整數n。

接下來n行每行n個整數,其中第i行第j個整數表示點i到j的距離(記為a[i,j])。

對於任意的x,y,z,資料保證 a[x,x]=0,a[x,y]=a[y,x] 並且 a[x,y]+a[y,z]>=a[x,z]。

輸出格式

輸出乙個整數,表示最短hamilton路徑的長度。

資料範圍

1≤n≤20

0≤a[i,j]≤107

輸入樣例:

50 2 4 5 1

2 0 6 5 3

4 6 0 8 3

5 5 8 0 5

1 3 3 5 0

輸出樣例:

18題目鏈結

二進位制壓縮就是說用乙個數來表示一種狀態

比如我們用0101010來表示第1、3、5位置已經被訪問過了(從0開始)

而0101010對應的二進位制數是2+8+32 = 42

我們就用42這個數來表示1、3、5這些位置都被訪問過

這裡點的個數不超過20,所以可以用這個方法來解題。

我們用dp[i][j]中i對應二進位制數的點已經被訪問過了,表示目前處於j點。

dp[i][j]對應的值來表示距離

則我們所求即dp[1《記i為對應的二進位制數,j表示目前處於哪個點,k來表示上乙個點。

根據哈密頓路徑的定義,每個點都只能被經過一次,所以j對應的上一次二進位制數i的位置為0

則上一次對應的二進位制數為i^(1<> k & 1來判斷k對應的位置是否為1

則可得狀態轉移方程為

dp[i][j] = min(dp[i][j], dp[i^(1

#include

#include

#include

#define ll long long

using

namespace std;

const

int maxn =

1e9+7;

int a[27]

[27];

int dp[

1<<20]

[27];

// dp[i][j]表示經過了i對應二進位制數的點 到第j-1個點的最短距離

int n;

inthamiton()

}}return dp[(1

<< n)-1

][n -1]

;}intmain()

二進位制狀態壓縮解決哈密頓最短路徑問題

右邊為第0位,左邊為第n 1位 1.取出整數n在二進位制表示下的第k位 n k 1 1001 0100 取出第4位 0000 1001 0000 0001 0000 0001 2.取出整數n在二進位制表示下的第0 k 1位 後k位 n 1 1001 0100 取出後5位 0010 0000 1 00...

Hamilton哈密頓最短路徑 二進位制狀態壓縮

哈密頓最短路徑即為從起點到終點,計算出經過圖中所有點的最短路徑。點較少的情況 由於途中點較少,可能會直接想到暴力列舉所有點的全排列,然後計算最短距離,其時間複雜度為 o n n o n n o n n 但是如果使用動態規劃,列舉每個點被經過的狀態的話,那麼可以將時間複雜度降到 o n 2 2n o ...

最短Hamilton路徑(二進位制狀態壓縮dp)

給定一張 n 個點的帶權無向圖,點從 0 n 1 標號,求起點 0 到終點 n 1 的最短hamilton路徑。hamilton路徑的定義是從 0 到 n 1 不重不漏地經過每個點恰好一次。輸入格式 第一行輸入整數nn。接下來n行每行n個整數,其中第ii行第jj個整數表示點i到j的距離 記為a i,...