HDU 5418 Victor and World 允许多次经过的TSP
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5418 Victor and World 允许多次经过的TSP相关的知识,希望对你有一定的参考价值。
题目链接:
hdu:
http://acm.hdu.edu.cn/showproblem.php?pid=5418
bestcoder(中文):
http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=619&pid=1002
Victor and World
Accepts: 99
Submissions: 644
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 262144/131072 K (Java/Others)
问题描述
经过多年的努力,Victor终于考到了飞行驾照。为了庆祝这件事,他决定给自己买一架飞机然后环游世界。他会驾驶一架飞机沿着规定的航线飞行。在地球上一共有n个国家,编号从1到n,各个国家之间通过m条双向航线连接,第i条航线连接第u?i??个国家与第v?i??个国家,通过这条航线需要消耗w?i??升油,且从1号国家可以直接或间接到达2到n中任意一个国家。 Victor一开始位于1号国家,他想知道从1号国家出发,经过各个国家至少一次并最后回到1号国家消耗的总油量的最小值是多少。
输入描述
第一行包含一个整数T,表示测试数据的组数。 每组测试数据的第一行有两个整数n和m,表示国家的个数和航线的条数。 接下来m行,每行三个整数u?i??, v?i??, w?i??,描述一条航线。 1≤T≤20。 1≤n≤16。 1≤m≤100000。 1≤w?i??≤100。 1≤u?i??,v?i??≤n。
输出描述
每组测试数据输出一行一个整数,即消耗的总油量的最小值。
输入样例
1 3 2 1 2 2 1 3 3
输出样例
10
题解:
这一道题与普通tsp的差别就在与状太转移变多了,设i,j为任意的两个点,s为压缩后的状态。dp[s][i]可以由dp[s][j]转移而来,这直接破坏普通TSP无后效性的前提。因此如果还想要用dp来解这道题,就要做一点改变创新了。
方法一:比较暴力的状态压缩
这里状态转移用的是刷表法
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn=(1<<16)+10; 8 static int INF; 9 10 int dp[maxn][33],cnt[maxn]; 11 12 int mat[33][33]; 13 14 int n,m; 15 16 void get_cnt(){ 17 memset(cnt,0,sizeof(cnt)); 18 for(int stat=0;stat<(1<<16);stat++){ 19 //统计每一个状态的已经访问了的节点的个数 20 for(int i=0;i<16;i++){ 21 if(stat&(1<<i)) cnt[stat]++; 22 } 23 } 24 } 25 26 void init(){ 27 memset(dp,0x3f,sizeof(dp)); 28 INF=dp[0][0]; 29 memset(mat,0x3f,sizeof(mat)); 30 } 31 32 int main(){ 33 get_cnt(); 34 int tc; 35 scanf("%d",&tc); 36 while(tc--){ 37 init(); 38 scanf("%d%d",&n,&m); 39 int u,v,w; 40 while(m--){ 41 scanf("%d%d%d",&u,&v,&w); 42 u--; v--; 43 if(w<mat[u][v]) 44 mat[u][v]=mat[v][u]=w; 45 } 46 dp[1][0]=0; 47 for(int s=1;s<(1<<n);s++){ 48 //做k次后能够保证引起后效性的那些转移也能得到最优解,有点像floyd算法的思想。 49 for(int k=0;k<=cnt[s];k++){ 50 for(int i=0;i<n;i++){ 51 //这里要做可行性减枝,否则时间会爆。 52 if(dp[s][i]!=INF){ 53 for(int j=0;j<n;j++){ 54 dp[s|(1<<j)][j]=min(dp[s|(1<<j)][j],dp[s][i]+mat[i][j]); 55 } 56 } 57 } 58 } 59 } 60 printf("%d\n",dp[(1<<n)-1][0]); 61 } 62 return 0; 63 }
以上是关于HDU 5418 Victor and World 允许多次经过的TSP的主要内容,如果未能解决你的问题,请参考以下文章
hdu 5418 Victor and World (状压dp)
BestCoder Round #52 (div.2) HDU 5418 Victor and World (DP+状态压缩)
HDOJ 5418 Victor and World 状压DP