日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU Victor and World (最短路+状态压缩)

發布時間:2023/11/29 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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 (最短路+状态压缩)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。