91 AcWing 最短Hamilton路徑

2022-03-16 20:46:36 字數 1621 閱讀 7045

原題鏈結

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

參考思路

np hard問題,暴力時間複雜度o(n∗n!)o(n∗n!)

這題正解其實是利用狀壓dp的方法來做,狀態轉移方程為

dp[i][j] = min

其中map陣列為權值,map[k][j]是點k到點j的權值

dp[i][j]表示當前已經走過點的集合為i,移動到j。所以這個狀態轉移方程就是找乙個中間點k,將已經走過點的集合i中去除掉j(表示j不在經過的點的集合中),然後再加上從k到j的權值

問題在於如何表達已經走過點的集合i,其實很簡單,假如走過0,1,4這三個點,我們用二進位制10011就可以表示,2,3沒走過所以是0

那麼走過點的集合i中去除掉點j也很容易表示i - (1 << j),比方說ij是1,那麼i = 10011,(1 << j) = 10,i - (1 << j) = 10001

那麼問題的答案就應該是dp[01....111][n-1],表示0~n-1都走過,且當前移動到n-1這個點

分析一下時間複雜度,n為20的時候,外層迴圈(1<<20),內層迴圈20,所以整體時間複雜度o(20∗220),這比o(n∗n!)快多了

#include#include#include#include#include#include#include#include#include#include#includetypedef long long ll;

using namespace std;

const ll llinf = 0x3f3f3f3f3f3f3f3f;

const int inf=0x3f3f3f3f;

const double eps=1e-6;

const int maxn=23;

int n;

int mp[maxn][maxn];

int dp[1<<20][maxn];

int main()

AcWing 91 最短Hamilton路徑

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

AcWing 91 最短Hamilton路徑

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

AcWing 1134 最短路計數

題目描述 給出乙個 n 個頂點 m 條邊的無向無權圖,頂點編號為 1 到 n。問從頂點 1 開始,到其他每個點的最短路有幾條。輸入格式 第一行包含 2 個正整數 n,m,為圖的頂點數與邊數。接下來 m 行,每行兩個正整數 x,y,表示有一條頂點 x 連向頂點 y 的邊,請注意可能有自環與重邊。輸出格...