給定一張 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,...