資料有更改
某鄉有n個村莊(11輸入格式:
村莊數n和各村之間的路程(均是整數)。
輸出格式:
最短的路程。
輸入樣例#1:
30 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 ...