HDU Victor and World (最短路+状态压缩)
題目鏈接:傳送門?
題意:
n個城市m條路。剛開始在點1,求把每一個城市都遍歷一邊最后回到1的花費的最小值。
分析:
我們首先須要預處理出隨意兩個國家之間的最短距離。由于數據范圍非常小,所以直接用Floyd即可了。之后,我們用f[S][i]表示訪問國家的情況為S,當前最后訪問的一個國家是i所須要的最小總油量。當中。S的二進制表示記錄了訪問國家的情況,S在二進制表示下的第i位(無論是從左往右還是從右往左都能夠)假設是1則表示第i個國家被訪問過了,否則表示第i個國家沒有被訪問過,那么f[S|(1<<i)][i]=min(f[S][j]+f[i][j])。當中i和j滿足S&(1<<j)=1且S&(1<<i)=0。最開始時,除了f[1][1]是0,其它情況都是無窮大,之后先枚舉S,再枚舉i(我驗題的時候由于這里搞反結果WA了)。那么終于的答案就是min(f[(1<<n)-1][i]+f[i][1])。當中i∈\in∈?[2,n]。
總復雜度為O(n3+n2?2n)O(n^3+n^2*2^n)O(n?3??+n?2???2?n??)。
轉自Bestcode。
以下說說我的狀態轉移,首先也處理好了每兩個城市之間的最短路。
然后DP[S][J]S轉換成二進制后1代表去過,0代表沒有去過最后留在J的最小花費,然后就枚舉S沒有去過的城市k
DP[S|(1<<k)][k]=min(DP[S][j]+mp[j][k])
代碼例如以下:
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> using namespace std;const int maxn = 18;const int inf = 0x3f3f3f3f;int dp[1<<maxn][maxn];int mp[maxn][maxn];void init(){memset(dp,inf,sizeof(dp));for(int i=0;i<maxn;i++)for(int j=0;j<maxn;j++)mp[i][j]=inf; }int main() {int t,n,m;scanf("%d",&t);while(t--){init();scanf("%d%d",&n,&m);for(int i=0;i<m;i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);mp[u][v]=min(mp[u][v],w);mp[v][u]=min(mp[v][u],w);}for(int i=0;i<maxn;i++) mp[i][i]=0;for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);}}}dp[1][1]=0;for(int i=0;i<(1<<n);i++){for(int j=0;j<n;j++){if(!(i&(1<<j))){for(int k=1;k<=n;k++){dp[i|(1<<j)][j+1]=min(dp[i|(1<<j)][j+1],dp[i][k]+mp[k][j+1]);}}}}int ans = inf;for(int i=1;i<=n;i++)ans = min(ans,dp[(1<<n)-1][i]+mp[i][1]);printf("%d\n",ans);}return 0; }
轉載于:https://www.cnblogs.com/gccbuaa/p/6939622.html
總結
以上是生活随笔為你收集整理的HDU Victor and World (最短路+状态压缩)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦里梦到女孩子代表什么
- 下一篇: 手游server之数据IO进化