题意:

  每个点都可以走多次的TSP问题:有n个点(n<=16),从点1出发,经过其他所有点至少1次,并回到原点1,使得路程最短。

思路:

  给了很多重边,选最小的留下即可。任意点可能无法直接到达,所以先执行一次floyd,算出任意点对之间可达的最短距离。

  (1)先考虑穷举的方法,将2~n个这n-1个数字的所有组合情况都算一遍,复杂度是 15!=1 3076 7436 8000,那是真的TSP了,不可能实现。

  (2)上面的方法中有没有多余的计算量?有的!里面还是有贪心可以运用的地方。对于当前遍历过了哪些点,我们只需要知道最后一个点是什么,中间的点的顺序是所所谓的,那么最后一个遍历的可以是2~n,而中间那些可以是其他的2~n中的数。起点1的距离更新为0,接下来递推就行了。递推方法是,穷举所有的中间状态s,然后以这些状态去穷举下一个到达的点(此点不在s中)。

  状态方程是:  dp[s|(1<<(i-1))][i]=min(dp[s][j]+g[j][i] ); s表示已经遍历过的点,j是最后那个点,i是未遍历过的点,从j走到i。

  290ms算可以了。

 #include <bits/stdc++.h>
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=;
int g[N][N], dp[<<N][N]; void floyd(int n)
{
for(int k=; k<=n; k++)
for(int i=; i<=n; i++)
for(int j=; j<=n; j++)
g[i][j]=min( g[i][j], g[i][k]+g[k][j]); } int cal( int n )
{
floyd(n);
memset(dp, 0x7f, sizeof(dp));
dp[][]=;
for(int s=; s<(<<n); s+=) //穷举状态
{
for(int i=; i<=n; i++) //设最后访问的点是i。i!=0
{
if( ( <<(i-) ) & s ) continue; //s中的第i位必须为0,即未访问过。
for(int j=; j<=n; j++)
{
if( s&(<<(j-)) ) //穷举s中出现过的1的位置。
dp[s|(<<(i-))][i]=min( dp[s|(<<(i-))][i], dp[s][j]+g[j][i] );
}
}
}
int ans=INF;
for(int i=; i<=n; i++) //最后访问的点不会是起点1。
ans=min(ans, dp[(<<n)-][i]+g[i][]);
return ans==INF? : ans; //只有1个点的情况
}
int main()
{
//freopen("input.txt", "r", stdin);
int t, n, m, a, b, c;
cin>>t;
while(t--)
{
scanf("%d%d", &n, &m);
memset(g, 0x3f, sizeof(g));
for(int i=; i<=n; i++) g[i][i]=; //初始化
for(int i=; i<m; i++)
{
scanf("%d%d%d",&a,&b,&c);
g[b][a]=g[a][b]=min(g[a][b], c);
}
printf("%d\n", cal(n));
}
return ;
}

AC代码

  

HDU 5418 Victor and World (可重复走的TSP问题,状压dp)的更多相关文章

  1. POJ 1185 - 炮兵阵地 & HDU 4539 - 郑厂长系列故事——排兵布阵 - [状压DP]

    印象中这道题好像我曾经肝过,但是没肝出来,现在肝出来了也挺开心的 题目链接:http://poj.org/problem?id=1185 Time Limit: 2000MS Memory Limit ...

  2. HDU - 6344 2018百度之星资格赛 1001调查问卷(状压dp)

    调查问卷  Accepts: 1289  Submissions: 5642  Time Limit: 6500/6000 MS (Java/Others)  Memory Limit: 262144 ...

  3. HDU 4539郑厂长系列故事――排兵布阵(状压DP)

    HDU 4539  郑厂长系列故事――排兵布阵 基础的状压DP,首先记录先每一行可取的所哟状态(一行里互不冲突的大概160个状态), 直接套了一个4重循环居然没超时我就呵呵了 //#pragma co ...

  4. hdu 2809(状压dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2809 思路:简单的状压dp,看代码会更明白. #include<iostream> #in ...

  5. hdu 2167(状压dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2167 思路:经典的状压dp题,前后,上下,对角8个位置不能取,状态压缩枚举即可所有情况,递推关系是为d ...

  6. ACM: HDU 5418 Victor and World - Floyd算法+dp状态压缩

    HDU 5418 Victor and World Time Limit:2000MS     Memory Limit:131072KB     64bit IO Format:%I64d & ...

  7. HDOJ 5418 Victor and World 状压DP

    水状压DP Victor and World Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java ...

  8. HDU 4284Travel(状压DP)

    HDU 4284    Travel 有N个城市,M条边和H个这个人(PP)必须要去的城市,在每个城市里他都必须要“打工”,打工需要花费Di,可以挣到Ci,每条边有一个花费,现在求PP可不可以从起点1 ...

  9. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

随机推荐

  1. 5.js屏蔽方向键,兼容IE和firefox

    document.onkeydown=function(e){ e=e||event; //屏蔽向左的方向键 if(e.keyCode==37){ alert('禁止向左的方向键!'); return ...

  2. AngularJS系统学习之Directive(指令)

    本文转自https://www.w3ctech.com/topic/1612 原文作者: Nicolas Bevacqua 原文:AngularJS’ Internals In Depth, Part ...

  3. window.open全屏

    window.open全屏   1. window.open(url,'资金计划项超支提醒','width='+(window.screen.availWidth-10)+',height='+(wi ...

  4. eclipse编辑窗口不见了(打开左边的java、xml文件,中间不会显示代码)

    转自:https://blog.csdn.net/u012062810/article/details/46729779?utm_source=blogxgwz4 1. windows-->re ...

  5. ubuntu 安装配置 JDK7和Android Studio(apt-get方式)

    Ubuntu 安装配置JKD 7 $ sudo add-apt-repository ppa:webupd8team/java $ sudo apt-get update $ sudo apt-get ...

  6. Acyclic Organic Compounds

    题意: 给一以1为根的字符树,给出每个节点的字符与权值,记 $diff_{x}$ 为从 $x$ 出发向下走,能走到多少不同的字符串,求问最大的$diff_{x} + c_{x}$,并求有多少个 $di ...

  7. 4.2 手写Java PriorityQueue 核心源码 - 实现篇

    上一节介绍了PriorityQueue的原理,先来简单的回顾一下 PriorityQueue 的原理 以最大堆为例来介绍 PriorityQueue是用一棵完全二叉树实现的. 不但是棵完全二叉树,而且 ...

  8. E20181120-hm

    checkerboard n. 西洋跳棋盘; checker n. 方格图案;

  9. bzoj 5120: [2017国家集训队测试]无限之环【最小费用最大流】

    玄妙的建图-- 这种平衡度数的题按套路是先黑白染色然后分别连ST点,相邻格子连黑向白连费用1流量0的边,然后考虑费用怎么表示 把一个点拆成五个,上下左右中,中间点黑白染色连ST, 对于连S的点,中点连 ...

  10. icekingdom(2018.10.17)

    一句话题意:给你一颗n个点的树,节点初始状态下都是白色,有q次修改,每次修改会把[li,ri]区间内的点染成黑色,并且问黑色点能形成几个联通块,然后会将所有点染回白色.(也就是说每次都只有[li,ri ...