题目链接:

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终于考到了飞行驾照。为了庆祝这件事,他决定给自己买一架飞机然后环游世界。他会驾驶一架飞机沿着规定的航线飞行。在地球上一共有nn个国家,编号从11到nn,各个国家之间通过mm条双向航线连接,第ii条航线连接第u_iu​i​​个国家与第v_iv​i​​个国家,通过这条航线需要消耗w_iw​i​​升油,且从11号国家可以直接或间接到达22到nn中任意一个国家。

Victor一开始位于11号国家,他想知道从11号国家出发,经过各个国家至少一次并最后回到11号国家消耗的总油量的最小值是多少。
输入描述
第一行包含一个整数TT,表示测试数据的组数。

每组测试数据的第一行有两个整数nn和mm,表示国家的个数和航线的条数。

接下来mm行,每行三个整数u_iu​i​​, v_iv​i​​, w_iw​i​​,描述一条航线。

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≤w​i​​≤100。

1\leq u_i, v_i \leq n1≤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来解这道题,就要做一点改变创新了。

方法一:比较暴力的状态压缩

  这里状态转移用的是刷表法

代码:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int maxn=(<<)+;
static int INF; int dp[maxn][],cnt[maxn]; int mat[][]; int n,m; void get_cnt(){
memset(cnt,,sizeof(cnt));
for(int stat=;stat<(<<);stat++){
//统计每一个状态的已经访问了的节点的个数
for(int i=;i<;i++){
if(stat&(<<i)) cnt[stat]++;
}
}
} void init(){
memset(dp,0x3f,sizeof(dp));
INF=dp[][];
memset(mat,0x3f,sizeof(mat));
} int main(){
get_cnt();
int tc;
scanf("%d",&tc);
while(tc--){
init();
scanf("%d%d",&n,&m);
int u,v,w;
while(m--){
scanf("%d%d%d",&u,&v,&w);
u--; v--;
if(w<mat[u][v])
mat[u][v]=mat[v][u]=w;
}
dp[][]=;
for(int s=;s<(<<n);s++){
//做k次后能够保证引起后效性的那些转移也能得到最优解,有点像floyd算法的思想。
for(int k=;k<=cnt[s];k++){
for(int i=;i<n;i++){
//这里要做可行性减枝,否则时间会爆。
if(dp[s][i]!=INF){
for(int j=;j<n;j++){
dp[s|(<<j)][j]=min(dp[s|(<<j)][j],dp[s][i]+mat[i][j]);
}
}
}
}
}
printf("%d\n",dp[(<<n)-][]);
}
return ;
}

方法二:先floyd,再直接上普通tsp的做法

代码:

 #include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std; const int maxn = ; int mat[maxn][maxn];
int dp[( << )+][maxn]; int n, m; void floyd() {
for (int k = ; k < n; k++) {
for (int i = ; i < n; i++) {
for (int j = ; j < n; j++) {
mat[i][j] = min(mat[i][j], mat[i][k] + mat[k][j]);
}
}
}
} void init() {
memset(mat, 0x3f, sizeof(mat));
for (int i = ; i < maxn; i++) mat[i][i] = ;
memset(dp, 0x3f, sizeof(dp));
} int main() {
int tc;
scanf("%d", &tc);
while (tc--) {
init();
scanf("%d%d", &n, &m);
int u, v, w;
while (m--) {
scanf("%d%d%d", &u, &v, &w);
u--; v--;
if (mat[u][v] > w) mat[u][v] = mat[v][u] = w;
}
floyd();
dp[][] = ;
//这里只是做出一个哈密顿通路
for (int s = ; s < ( << n); s++) {
for (int i = ; i < n; i++) {
if (s&( << i)) {
for (int j = ; j < n; j++) {
if ((s&( << j))== ) {
dp[s | ( << j)][j] = min(dp[s | ( << j)][j], dp[s][i] + mat[i][j]);
}
}
}
}
}
//补回路
int ans = 0x3f3f3f3f;
for (int i = ; i < n; i++) {
ans = min(ans, dp[( << n) - ][i] + mat[i][]);
}
if (n == ) printf("0\n");
else printf("%d\n", ans);
}
return ;
}

HDU 5418 Victor and World 允许多次经过的TSP的更多相关文章

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

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

  2. HDU 5418 Victor and World(状压DP+Floyed预处理)

    Victor and World Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Other ...

  3. BestCoder Round #52 (div.2) HDU 5418 Victor and World (DP+状态压缩)

    [题目链接]:pid=5418">click here~~ [题目大意]: 问题描写叙述 经过多年的努力,Victor最终考到了飞行驾照. 为了庆祝这件事,他决定给自己买一架飞机然后环 ...

  4. HDU 5418 Victor and World (状态压缩dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5418 题目大意:有n个结点m条边(有边权)组成的一张连通图(n <16, m<100000 ...

  5. HDU 5418——Victor and World——————【状态压缩+floyd】

    Victor and World Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/131072 K (Java/Other ...

  6. HDU 5418 Victor and World (Floyd + 状态压缩DP)

    题目大意:从起点 1 开始走遍所有的点,回到起点 1 ,求出所走的最短长度. 思路:首先利用 Floyed 求出任意两点之间的最短距离 dis[i][j].求出任意两点之间的最短距离后,运用动态规划. ...

  7. HDU 5418 Victor and World (可重复走的TSP问题,状压dp)

    题意: 每个点都可以走多次的TSP问题:有n个点(n<=16),从点1出发,经过其他所有点至少1次,并回到原点1,使得路程最短. 思路: 给了很多重边,选最小的留下即可.任意点可能无法直接到达, ...

  8. HDU - 5067 / HDU - 5418 TSP

    集合表示多用[0,n)表示方法 HDU - 5067 经典TSP,每个顶点恰经过一次最优 #include<bits/stdc++.h> #define rep(i,j,k) for(in ...

  9. 【hdu 5418】 Victor and world

    [题目链接] 点击打开链接 [算法] 状压DP f[i][S]表示走的最后一步在i,状态为S 于是我们可以用最短路径 + 状压DP解决此题,由于不存在负边,所以可以用dijkstra+堆优化 [代码] ...

随机推荐

  1. 解决在 win10 下 vs2017 中创建 MFC 程序拖放文件接收不到 WM_DROPFILES 消息问题

    解决方案 这个问题是由于 win10 的安全机制搞的鬼,即使以管理员权限运行也不行,因为它会把 WM_DROPFILES 消息过滤掉,那怎么办呢?只需在窗口初始化 OnInitDialog() 里添加 ...

  2. QEMU 模拟运行 VxWorks 6.6

    QEMU 模拟运行 VxWorks 6.6 项目简介 本项目是在 Windows 系统编译运行 X86 平台 VxWorks 6.6 系统,使用的模拟软件是 qemu for Windows Host ...

  3. drag element

    <div id="logDiv" draggable="true" style="border: 2px dotted red; width: ...

  4. 2017-2018-1 20155308&20155321&20155330《信息安全技术》实验三——数字证书应用1

    2017-2018-1 20155308&20155321&20155330<信息安全技术>实验三--数字证书应用1 实验目的 了解PKI体系 了解用户进行证书申请和CA颁 ...

  5. PhoneGap3.2安装步骤

    1.首选安装好JDK.Android SDK.Ant 配置如下:        系统环境变量        ANDROID_HOME Value: C:\Development\adt-bundle\ ...

  6. WebAPI学习笔记

    WebAPI WebApi是添加到Asp.Net平台的一个新特性,可以快速的创建Web服务,并对客户端提供HTTP的API调用接口 WebApi是建立在MVC框架基础之上,但不属于MVC的一部分. 序 ...

  7. Html+CSS 学习第二天

    趁着这两天,将html和CSS基本上学了一遍,大家如果想学习的话,可以百度w3cSchool,进行学习. 基础我就不说了,直接将我做的一个登陆页面放上去.刚学完CSS,写个漂亮的登录界面恶心死我了,感 ...

  8. python编码和小数据池

    python_day_6 一. 回顾上周所有内容一. python基础 Python是一门解释型. 弱类型语言 print("内容", "内容", end=&q ...

  9. Jmeter接口测试(四)传递参数

    参数设置 Jmeter 支持通过 查询字符串参数(Query String Parameters) 或者 Request body 请求体来传递参数. 1.get请求是普通键值对 get请求一般通过p ...

  10. Lua学习笔记(2): 流程控制与循环以及初涉迭代器

    条件判断语句 --if...语句 if (表达式) then --表达式为1时执行的语句 end --if...else语句 if (表达式) then --表达式为1时执行的语句 else --表达 ...