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
经过多年的努力,Victor终于考到了飞行驾照。为了庆祝这件事,他决定给自己买一架飞机然后环游世界。他会驾驶一架飞机沿着规定的航线飞行。在地球上一共有nn个国家,编号从11到nn,各个国家之间通过mm条双向航线连接,第ii条航线连接第u_iui个国家与第v_ivi个国家,通过这条航线需要消耗w_iwi升油,且从11号国家可以直接或间接到达22到nn中任意一个国家。Victor一开始位于11号国家,他想知道从11号国家出发,经过各个国家至少一次并最后回到11号国家消耗的总油量的最小值是多少。
第一行包含一个整数TT,表示测试数据的组数。每组测试数据的第一行有两个整数nn和mm,表示国家的个数和航线的条数。接下来mm行,每行三个整数u_iui, v_ivi, w_iwi,描述一条航线。1\leq T\leq 201≤T≤20。1\leq n\leq 161≤n≤16。1\leq m\leq 1000001≤m≤100000。1\leq w_i\leq 1001≤wi≤100。1\leq u_i, v_i \leq n1≤ui,vi≤n。
每组测试数据输出一行一个整数,即消耗的总油量的最小值。
1 3 2 1 2 2 1 3 3
10
题解:
这一道题与普通tsp的差别就在与状太转移变多了,设i,j为任意的两个点,s为压缩后的状态。dp[s][i]可以由dp[s][j]转移而来,这直接破坏普通TSP无后效性的前提。因此如果还想要用dp来解这道题,就要做一点改变创新了。
方法一:比较暴力的状态压缩
这里状态转移用的是刷表法
代码:
![](/assets/blank.gif)
![](/assets/blank.gif)
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 }
View Code
方法二:先floyd,再直接上普通tsp的做法
代码:
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 6 const int maxn = 33; 7 8 int mat[maxn][maxn]; 9 int dp[(1 << 16)+10][maxn]; 10 11 int n, m; 12 13 void floyd() { 14 for (int k = 0; k < n; k++) { 15 for (int i = 0; i < n; i++) { 16 for (int j = 0; j < n; j++) { 17 mat[i][j] = min(mat[i][j], mat[i][k] + mat[k][j]); 18 } 19 } 20 } 21 } 22 23 void init() { 24 memset(mat, 0x3f, sizeof(mat)); 25 for (int i = 0; i < maxn; i++) mat[i][i] = 0; 26 memset(dp, 0x3f, sizeof(dp)); 27 } 28 29 int main() { 30 int tc; 31 scanf("%d", &tc); 32 while (tc--) { 33 init(); 34 scanf("%d%d", &n, &m); 35 int u, v, w; 36 while (m--) { 37 scanf("%d%d%d", &u, &v, &w); 38 u--; v--; 39 if (mat[u][v] > w) mat[u][v] = mat[v][u] = w; 40 } 41 floyd(); 42 dp[1][0] = 0; 43 //这里只是做出一个哈密顿通路 44 for (int s = 1; s < (1 << n); s++) { 45 for (int i = 0; i < n; i++) { 46 if (s&(1 << i)) { 47 for (int j = 0; j < n; j++) { 48 if ((s&(1 << j))== 0) { 49 dp[s | (1 << j)][j] = min(dp[s | (1 << j)][j], dp[s][i] + mat[i][j]); 50 } 51 } 52 } 53 } 54 } 55 //补回路 56 int ans = 0x3f3f3f3f; 57 for (int i = 1; i < n; i++) { 58 ans = min(ans, dp[(1 << n) - 1][i] + mat[i][0]); 59 } 60 if (n == 1) printf("0\n"); 61 else printf("%d\n", ans); 62 } 63 return 0; 64 }
View Code
转载于:https://www.cnblogs.com/fenice/p/5293657.html
HDU 5418 Victor and World 允许多次经过的TSP相关推荐
- hdu 5418 Victor and World (floyd+状压dp)
题目大意:可重复访问顶点的TSP问题. 解法:点击打开链接 坑点:n=1 #include<iostream> #include<cstdio> #include<cst ...
- 【HDU - 5418】Victor and World(tsp旅行商问题,状压dp,floyd最短路,图论)
题干: After trying hard for many years, Victor has finally received a pilot license. To have a celebra ...
- hdu 5420 Victor and Proposition 线段树建图+强连通分量
题意: http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=620&pid=1003 题目求有多少对互为充要 ...
- hdu 5418(状态压缩dp+Floyd)
点击打开链接 解题思路:这道题目和TSP问题很相似,唯一不同的是同一个点可以重复走几次.... 这道题目只有16个顶点,所以很容易想到状态压缩dp,dp[i][j]表示到达顶点i时的状态为j的最小花费 ...
- 最短哈密顿环 退火_hdu 5418 Victor and World (最短哈密顿回路)
给你n个国家,m条路线:u_i与v_i之间的距离w_i. 输出从1号国家出发经过每个国家至少一次再回到1号国家的最短距离. [官方题解]: 我们首先需要预处理出任意两个国家之间的最短距离,因为数据范围 ...
- hdu 5420 Victor and Proposition(强连通+线段树建图)
题意:给出一棵树,每个点都给一个x,d,代表它和x这个点以及以下深度差小于d的点都有一条有向边,求互相可达的u,v对数. 做法:可以很容易发觉如果我们把点连好然后直接找强连通分量,然后答案就是每个强连 ...
- linux系统起来时间,linux 系统时间调整
BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA] 3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 1280 MBSubmit: 3127 ...
- linux中自动启动不了怎么办,linux:/etc/rc.local 不能自动启动问题
前段时间安装LNMP环境,配置/etc/rc.local的时候配置了启动mysql.nginx.php以及关闭防火墙,可结果重启了七八次还是自启动不了后来终于找到原因了 看下图: /etc/rc.lo ...
- Victor and World(spfa+状态压缩dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 Victor and World Time Limit: 4000/2000 MS (Java/ ...
最新文章
- Android应用开发—TextView的动态创建
- [UOJ422]小Z的礼物
- JBoss Eclipse IDE
- 1874 素数和最大 - Wikioi
- mysql 异常关机后 无法查数据_MySQL数据库非法关机造成数据表损坏怎么排查 | 学步园...
- Hadoop之NameNode和SecondaryNameNode工作机制详解
- c++ mqtt客户端_MQTT详解及百度物接入连接手机测试(含源码) 秦子帅
- 接口文档下的渗透测试(Swagger)
- 基于MVC4+EasyUI的Web开发框架经验总结(6)--在页面中应用下拉列表的处理
- 灵活应对算法大赛新挑战,极清晰比赛思路你值得拥有
- setpairint,int 的用法
- Leetcode201. Bitwise AND of Numbers Range数字范围按位与
- Coreldraw x6离线激活注册机免费下载安装教程
- BUUCTF pwn rootersctf_2019_xsh
- 关于MFi认证你所必须要知道的事情
- 【git 常用配置及常用命令】
- Webpack--模块热替换(HMR)
- swap未禁用导致的k8s NotReady
- TP-LINK TL-WR841N 路由变无线交换机设置
- 【经典面试题】strcmp 函数的实现