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

2021-09-25 05:55:37 字數 1148 閱讀 7534

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

輸入格式

第一行輸入整數nn。

接下來n行每行n個整數,其中第ii行第jj個整數表示點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]≤1e7

輸入樣例:

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知識點:二進位制狀態壓縮dp

思路:1.brute force

求出n個點的全排列,計算每種情況的路徑值,取最小的值。 o(n * n !) 超時。

2.二進位制狀態壓縮dp

把 n 用二進位制表示,每一位只有0和1,我們把1表示這個點已經經過,0表示這個點未被經過。

判斷語句只有1是合法的,意思是剛剛經過了這個點,此時的上乙個狀態被經過了。

建立乙個二維陣列dp[i][j]表示狀態為 i ,走到 j 點時的最短路徑。

剛開始dp[1][0]=0表示起始點0 已經經過,且最短路為0。把dp陣列初始為正無窮。

最終的目標是所有點都被經過,也就是轉態為n個1(111111…) 走到第n-1個點,所以

dp[(1<#include#include#includeusing namespace std;

const int mmax=1e6+10;

typedef long long ll;

const int inf=0x3f3f3f3f;

const int m=1<<20,n=20;

ll dp[m][n],weight[n][n];

int main()

} dp[1][0]=0;

for(int i=0;i<(1<>j&1)}}

}} cout

}

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

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

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

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

最短Hamilton路徑

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