P1171 售貨員的難題

2022-03-04 21:12:46 字數 1678 閱讀 8676

資料有更改

某鄉有n個村莊(11輸入格式:

村莊數n和各村之間的路程(均是整數)。

輸出格式:

最短的路程。

輸入樣例#1:

3

0 2 1

1 0 2

2 1 0

輸出樣例#1:

3

輸入解釋

3 0 2 1

1 0 2

2 1 0

solution:

法一:經典的狀壓dp題目。設f[i][j]表示某個狀態的最短距離,其中i的二進位制表示下的各位若為1則表示該點被訪問過,j表示當前在j點,則容易得到狀態轉移方程:

f[i][j]=min][v]+w[j][v]}

由於最後要回到起點1,所以最後判斷一下:

ans=min。

狀壓**:

#include#define il inline

#define ll long long

using

namespace

std;

const

int n=1

<<20

;int n,w[25][25],f[n][22],ans=0x3f3f3f3f

;int

main()

法二:當然本題也可以搜尋+剪枝。

剪枝1:優化搜尋順序,按邊從小到大排序。

剪枝2:最優性剪枝,若大於當前最優值則return。

剪枝3:可行性剪枝,將當前到沒訪問的點的距離都假設為1,若當前走過的距離加上沒訪問的點個數仍大於當前最優值,則return。

搜尋**:

#include#include

#include

using

namespace

std;

int n,min1=200010,sum,minv[21],mind=200010

;bool vis[21

];struct

nodea[

21][21],b[21

];void dfs(int q,int

last)

for(int i=2;i<=n;i++)

if(!vis[a[last][i].id])

}bool

cmp(node a,node b)

intmain()

minv[i]=a[i][1].dis;//

minv[i]表示i村莊到1的距離

if(i!=1)mind=min(mind,minv[i]);//

表示所有村莊到1的最短距離(不包括1到1)

sort(a[i]+1,a[i]+n+1,cmp);//

讀資料時每次得到一行的值後對邊值排序。這樣可以更快得到較優值。

} vis[

1]=1

; dfs(

1,1);

cout

}

P1171 售貨員的難題

題目描述 某鄉有nn個村莊 1 1 all 1 路徑總長度最小 除錯日誌 又把 1 i 1 寫成了 1 num 1 小插曲 卡空間卡到阿蘇發稿地方od撒龍捲風no,然後這題常規做法只能開 o 過 經典狀壓dp dp i j 表示 i 狀態下最後乙個點走 j 的最短路徑長度 轉移見 include i...

洛谷 P1171 售貨員的難題

經典的旅行商問題 dp i j 表示從j出發,去遍歷狀態為i的點,並且回到起點的最短路徑長度 初始化 dp 0 i dis i,起點 即從點i哪兒哪兒也不遍歷,直接回到起點的路徑長度 對於每乙個狀態i,列舉要從哪個點出發,去遍歷這個狀態 然後列舉這個點要直接前往的狀態中的某個點 最後輸出dp 總狀態...

P1171 售貨員的難題 暴力dp

題面 著名的tsp問題,npc問題 對於資料大的情況,我們可以使用一系列近似演算法進行尋找解。對於資料規模小的情況,我們可以直接暴力dp 一開始寫了乙個dfs,然後就被n 20的資料卡爆了 include include include includeusing std min const int ...