HDU 4114 Disney's FastPass
传送门
状压dp+最短路。
一个无向图,接下来给出一些兴趣点,每个兴趣点被访问时有一定耗时。找一条从起点开始访问所有兴趣点再回到起点耗时最短的路(必须访问所有兴趣点,途中可以经过任意点(经过任意点包括兴趣点都不耗时),全程总耗时包括访问兴趣点和途经所有边)。每个兴趣点在一些点有通票,经过这些点中任意一个就可以拿到这个兴趣点的通票,拿到通票之后意味着访问这个兴趣点的耗时可以缩短。
题意比较复杂,给定的兴趣点的最大值是8
。我们可以考虑用二进制来表示当前访问过的兴趣点以及当前拿到哪些兴趣点的通票,所以这两维状态的数量都是2^8=256
种。每个点含有的通票都是来自兴趣点的,所以也用同样的状态表示方法来表示每个点含有哪些兴趣点的通票(在输入时完成)。
所谓状态转移,一个是当前状态可转移到哪些状态,另一个是可转移的状态的值怎么用当前状态的值来表示。dp[k][i][j]
表示当前从起点走到k
点(已获取k
点含有的通票),拿到的通票的二进制状态的十进制表示为i
,访问过的兴趣点的二进制状态的十进制表示为j
,在此情况下的最短耗时。
可转移三种状态,一种是访问状态(转移到当前还没有访问过的兴趣点),一种是经过状态(转移到所有点(包括所有兴趣点)),一种是答案状态(如果当前状态已访问过所有兴趣点)。而对于新状态的值,从当前点到新点肯定要走最短路,需要预先floyd
一遍。
因为访问兴趣点需要耗时,所以每个兴趣点只访问一次就好了(这与下句话并不冲突)。题目中说可能有多个兴趣点是同一个点,那么就要访问这个点多次,每次都当成一个兴趣点。
最后要注意的问题就是dp
数组每一维的循环次序,可以把i
,j
当成同一组,对k
的循环一定要在i
,j
的下层进行。为什么?因为当前状态完全可以转移到k
更小的状态,但是转移到的状态的i
,j
的值一定不会减小。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <queue>
using namespace std; // 传说中的状压dpconst int INF = 0x3F3F3F3F;
const int MAXN = 51;
int N, M, K, X;
int g[MAXN][MAXN];int pos[8], T[8], FT[8];
int pass[MAXN];int dp[MAXN][1 << 8][1 << 8];
int ans;void init()
{memset(g, 0x3F, sizeof g);memset(pass, 0, sizeof pass);memset(dp, 0x3F, sizeof dp);for (int i = 1; i <= N; i++) g[i][i] = 0;ans = INF;
}void floyd()
{for (int k = 1; k <= N; k++){for (int i = 1; i <= N; i++){for (int j = i + 1; j <= N; j++){if (g[i][k] != INF && g[k][j] != INF && g[i][k] + g[k][j] < g[i][j]){g[i][j] = g[j][i] = g[i][k] + g[k][j];}}}}
}void run()
{dp[1][0][0] = 0; // 初始状态for (int i = 0; i < (1 << K); i++){for (int j = 0; j < (1 << K); j++){for (int k = 1; k <= N; k++){int t = dp[k][i][j];if (t != INF){if (j == ((1 << K) - 1)){ans = min(ans, t + g[k][1]);continue;}for (int n = 0; n < K; n++) // 1{if (!(j&(1 << n)) && g[k][pos[n]] != INF) // 不加也行{int& u = dp[pos[n]][i | pass[pos[n]]][j | (1 << n)];u = min(u, t + g[k][pos[n]] + (i&(1 << n) ? FT[n] : T[n]));}}for (int n = 1; n <= N; n++) // 2 1,2部分可以调换位置,无影响{if (g[k][n] != INF) // 不加也行{int& u = dp[n][i | pass[n]][j];u = min(u, t + g[k][n]);}}}}}}
}int main()
{int a, b, c;scanf("%d", &X);for (int i = 1; i <= X; i++){scanf("%d%d%d", &N, &M, &K);init();for (int j = 0; j < M; j++){scanf("%d%d%d", &a, &b, &c);g[a][b] = g[b][a] = c;}for (int j = 0; j < K; j++){scanf("%d%d%d%d", &pos[j], &T[j], &FT[j], &a);for (; a--;){scanf("%d", &b);pass[b] |= 1 << j;}}floyd();run();printf("Case #%d: %d\n", i, ans);}return 0;
}
HDU 4114 Disney's FastPass相关推荐
- hdu 4114 Disney's FastPass 状压dp
点击打开链接 题意: 游戏园里有N个区域,有M条边连接这N个区域,有K个要访问的景点.对于每个景点告诉你这个景点所在的区域,要访问这个景点需要等待一定时间,如果没有FastPass,等待时间有Ti,否 ...
- HDU 4114 Disney's FastPass(状压dp)
题意就是给你一些点,有的地方有景区,有的地方有某些景点的优先票,拿优先票去景点和不拿的时间不一样.问从地点1出发去所有景点再回来的最短时间. 得把景点,景区进行状压.即dp[i][j][k]代表参观景 ...
- hdu4114.Disney's FastPass
http://acm.hdu.edu.cn/showproblem.php?pid=4114 题意:给定一个带权无向同(<=50)和图中若干个点(<=8),..现在要你'游'这些点,'游' ...
- 【LDU】 Week2自测 Disney‘s FastPass | 状压dp、Floyd
这题是hdu 4114... 跟着19的打了打周测,发现个好题 写了写还wa了一发 题目大意: 给出n个点,k个要旅游的景点,然后给出k个景点的信息(位置,t,ft,门票所在地点),t于ft表示,如果 ...
- HDU Disney's FastPass
原创:http://acm.hdu.edu.cn/showproblem.php?pid=4114 题意:从1开始遍历完k个给定点,最终回到1,的最少时间 思路:首先是floyd预处理出任意两点之间的 ...
- hdu Disney's FastPass(状态压缩dp)
这种题我一直喜欢用bfs搞的,但是这个题不太好bfs,主要是我刚开始想的是通过边进行状态转移,这样很不好写...于是就坑爹了,调了很久sample都没出... 于是学习了一下别人的思想...通过&qu ...
- 杭电OJ分类题目(4)-Graph
原题出处:HDOJ Problem Index by Type,http://acm.hdu.edu.cn/typeclass.php 杭电OJ分类题目(4) HDU Graph Theory - U ...
- 【转载】图论 500题——主要为hdu/poj/zoj
转自--http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...
- 【HDOJ图论题集】【转】
1 =============================以下是最小生成树+并查集====================================== 2 [HDU] 3 1213 How ...
最新文章
- python打包zip文件_python 解压文件,合并文件 打包成zip格式文件 生成MD5值
- 音视频技术开发周刊 69期
- 程序员面试什么最重要?
- open函数和close函数的使用
- 一道多线程通信实例分析
- Secure CRT 自动记录日志
- mysql 压力测试知乎_MySQL查看SQL语句执行效率和mysql几种性能测试的工具
- 梯度下降和EM算法,kmeans的em推导
- “加薪”“洗手间”都不能提?亚马逊内部员工通讯 App 曝光!
- 163邮箱苹果设置不成功_苹果变安卓不是不可能,Corellium让iPhone成功安装安卓系统...
- 微信小程序云开发教程-JavaScript入门(6)-常用函数
- Android Wear和二维码
- linux中/etc/hosts文件的含义
- 编写一个方法,将一段文本中的各个单词的字母顺序翻转题
- 2018年度10大新兴技术:人工智能、量子计算、增强现实等
- 计算机蓝屏代码0xc0000020,Win10系统运行程序提示“损坏的映像 错误0xc0000020”怎么解决...
- Windows下及linux下PVM并行计算平台的搭建
- 教你如何避开雪花算法的坑
- EAS BOS 单据开发下拉列表监听方法
- 11个超好用的SVG编辑工具