题意就是给你一些点,有的地方有景区,有的地方有某些景点的优先票,拿优先票去景点和不拿的时间不一样。问从地点1出发去所有景点再回来的最短时间。

得把景点,景区进行状压。即dp[i][j][k]代表参观景点状态为i,景区状态为j,停在k的最短时间。

先floyd一下处理出最短路。

对于一种状态i,j,为了保证dp[i][j][k]在递推的时候是最短时间可以先用2个(1-n)for循环进行更新,因为可能有的位置的状态是-1即不存在。事实上只要有一个点存在i与j的状态,那么其他点必定都存在i,j这个状态。

然后再去更新去看景点的情况,在做过刚才那个处理后,其实只需要看当前位置下的景点就行,看网上其他人的代码则是遍历去看所有景点,如果这样做的话就不用先做那个处理了,可以放在一起做。

另外,还有一个优化,如果已经参观了那个节点,那么就强行给他一个票,其实就是在其他条件都相同的情况下(在同一个点,经过同样的景点),有票跟没票的比较。这样的话,参观景点的集合就是票的集合的子集了。然后又容易看出其实i跟j的递推顺序交换也是一样的,所以就用了枚举子集的办法,然后把子集从小到大推。

竟然刷到rank1了。577ms。

AC代码:

#include<cstdio>
#include<ctype.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdlib>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<string.h>
#include<string>
#include<sstream>
#include<bitset>
using namespace std;
#define ll __int64
#define ull unsigned long long
#define eps 1e-8
#define NMAX 1<<29
#define MOD 1000000
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1)
template<class T>
inline void scan_d(T &ret)
{char c;int flag = 0;ret=0;while(((c=getchar())<'0'||c>'9')&&c!='-');if(c == '-'){flag = 1;c = getchar();}while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();if(flag) ret = -ret;
}int dp[1<<8][1<<8][55],dist[55][55];struct node
{int t,ft;
};
node no[10];inline void update(int &a, int b)
{if(a < 0 || a > b)a = b;
}void floyd(int n)
{for(int k = 1; k <= n; k++)for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)dist[i][j] = min(dist[i][j],dist[i][k]+dist[k][j]);
}int pos[10],getft[55];
int s[1<<8];
int main()
{
#ifdef GLQfreopen("input.txt","r",stdin);
//    freopen("o.txt","w",stdout);
#endifint t,n,m,K,cas = 1;scanf("%d",&t);while(t--){scanf("%d%d%d",&n,&m,&K);for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++)dist[i][j] = NMAX;dist[i][i] = 0;}for(int i = 1; i <= m; i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);dist[u][v] = dist[v][u] = w;}floyd(n);memset(getft,0,sizeof(getft));for(int i = 0; i < K; i++){int tmp;scanf("%d%d%d%d",&pos[i],&no[i].t,&no[i].ft,&tmp);while(tmp--){int t1;scanf("%d",&t1);getft[t1] |= (1<<i);}}for(int i = 0; i < (1<<K); i++)for(int j = 0; j < (1<<K); j++)for(int k = 1; k <= n; k++) dp[i][j][k] = -1;dp[0][0][1] = 0;for(int j = 0; j < (1<<K); j++){int nct = 0;for(int i = j; i ; i = (i-1)&j) s[nct++] = i;s[nct++] = 0;for(int w = nct-1; w >= 0; w--){int i = s[w];for(int k = 1; k <= n; k++) if(dp[i][j][k] >= 0){for(int l = 0; l < K; l++) if(!(i&(1<<l))){int cost = dist[k][pos[l]];if(j&(1<<l)) cost += no[l].ft;else cost += no[l].t;update(dp[i|(1<<l)][j|getft[pos[l]]|(1<<l)][pos[l]],dp[i][j][k]+cost);}for(int l = 1; l <= n; l++)update(dp[i][j|getft[l]][l],dp[i][j][k]+dist[k][l]);}
//                for(int k = 1; k <= n; k++) if(dp[i][j][k] >= 0)//这种递推就可以只看自己点上面的景点
//                {
//                    for(int l = 1; l <= n; l++)
//                        update(dp[i][j|getft[l]][l],dp[i][j][k]+dist[k][l]);
//                }
//                for(int k = 1; k <= n; k++) if(dp[i][j][k] >= 0)
//                {
//                    for(int l = 0; l < K; l++) if(!(i&(1<<l)))
//                    {
//                        if(pos[l] != k) continue;
//                        int cost;
//                        if(j&(1<<l)) cost = no[l].ft;
//                        else cost = no[l].t;
//                        update(dp[i|(1<<l)][j|getft[pos[l]]|(1<<l)][pos[l]],dp[i][j][k]+cost);
//                    }
//                }}}printf("Case #%d: %d\n",cas++,dp[(1<<K)-1][(1<<K)-1][1]);}return 0;
}

HDU 4114 Disney's FastPass(状压dp)相关推荐

  1. hdu 4114 Disney's FastPass 状压dp

    点击打开链接 题意: 游戏园里有N个区域,有M条边连接这N个区域,有K个要访问的景点.对于每个景点告诉你这个景点所在的区域,要访问这个景点需要等待一定时间,如果没有FastPass,等待时间有Ti,否 ...

  2. 【LDU】 Week2自测 Disney‘s FastPass | 状压dp、Floyd

    这题是hdu 4114... 跟着19的打了打周测,发现个好题 写了写还wa了一发 题目大意: 给出n个点,k个要旅游的景点,然后给出k个景点的信息(位置,t,ft,门票所在地点),t于ft表示,如果 ...

  3. HDU - 4856 Tunnels (预处理+状压dp)

    HDU - 4856 Tunnels (预处理+状压dp) [hud链接] [vj链接] 题目 Problem Description Bob is travelling in Xi'an. He f ...

  4. HDU 5691 Sitting in Line 状压dp

    Sitting in Line 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5691 Description 度度熊是他同时代中最伟大的数学家,一切 ...

  5. HDU 4114 Disney's FastPass

    传送门 状压dp+最短路. 一个无向图,接下来给出一些兴趣点,每个兴趣点被访问时有一定耗时.找一条从起点开始访问所有兴趣点再回到起点耗时最短的路(必须访问所有兴趣点,途中可以经过任意点(经过任意点包括 ...

  6. HDU 4899 Hero meet devil (状压DP, DP预处理)

    题意:给你一个基因序列s(只有A,T,C,G四个字符,假设长度为n),问长度为m的基因序列s1中与给定的基因序列LCS是0,1......n的有多少个? 思路:最直接的方法是暴力枚举长度为m的串,然后 ...

  7. HDU 3001 Travelling (三进制状压dp)

    题意 n(n<=10)n(n个城市,知道每个城市间的旅行费用,但每个城市最多走两遍.问最小花费是多少 . 也就是每个城市可以走两次的tsp问题. 分析 最多走两次,三进制0 1 2可满足,即用三 ...

  8. HDU 4856 Tunnels(BFS+状压DP)

    HDU 4856 Tunnels 题目链接 题意:给定一些管道.然后管道之间走是不用时间的,陆地上有障碍.陆地上走一步花费时间1,求遍历全部管道须要的最短时间.每一个管道仅仅能走一次 思路:先BFS预 ...

  9. hdu 4778 Gems Fight! 状压dp

    转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...

最新文章

  1. python读写二进制文件(读写字节数据)
  2. 集成学习-Bagging集成学习算法随机森林(Random Forest)
  3. 索引创建以及优化_1
  4. wcf http 返回图片
  5. Linux网络编程一步一步学-select详解
  6. LeetCode 1243. 数组变换
  7. 微服务 注册中心的作用_102,谈谈微服务注册中心zookeeperamp;Eureka
  8. Nginx启动后无法访问页面
  9. flask-sqlalchemy mysql_flask-sqlalchemy总结
  10. iframe父页面与子页面之间的传值问题
  11. 成都哪所专科院校有计算机专业,成都哪些高职院校有计算机应用技术
  12. 【有限元分析】有限元仿真分析与解析解的结果对比——以阶梯轴的静力分析为例
  13. 鸿蒙系统怎么设置上网速度,苹果手机上网速度慢怎么办!手把手教你如何解决...
  14. 最基础硬件学习 | 简单闪烁灯制作
  15. 复旦大学计算机研究生初试分数线,复旦大学计算机研究生复试分数线
  16. 腾讯AI Lab发布智能创作助手「文涌 (Effidit)」,用技术助力「文思泉涌」
  17. 【约瑟夫环】Java实现:100个人开始从1开始报数,每当报数到3,报数3的人离开,求最后留下来人的位置。
  18. 在J1939中多帧数据如何发送,它是通过TP.CM_BAM和TP_DT报文发送
  19. angularjs学习总结 详细教程(转载)
  20. android 获取电流参数,Android编程实现添加低电流提醒功能的方法

热门文章

  1. android 窗口圆角
  2. MMC、EMMC、MCP、EMCP区别
  3. python猜年龄代码_Python实现猜年龄游戏代码实例
  4. 功能篇------android 实现“摇一摇”功能
  5. SpringBoot使用JavaMailSender发送邮件:com.sun.mail.smtp.SMTPSendFailedException: 451 MI:SFQ 163 smtp7
  6. PS快速将白底图片变为透明图片的解决办法
  7. miui系统android os,color os对比miui 一加手机刷Color OS与MIUI系统体验对比评测
  8. 网易容器云平台的微服务化实践(一)
  9. POS接口与GE接口区别
  10. AD软件PCB转PADS