DAG求最短路--TSP变形--状压dp

DAG状压dp的一种

题目:

$m$个城市,$n$张车票,第i张车票上的时间是$t_i$, 求从$a$到$b$的最短时间,如果无法到达则输出“impossible”

解法:

考虑状态:“现在在城市$v$,此时还剩下的车票的集合为$S$”这样的状态。从这个状态出发,使用一张车票移动到$i \in S$移动到相邻的城市$u$,就相当于转移到了“在城市$u$,此时还剩下的车票的集合为$S/ { i }$”这个状态。

把这个转移看成一条边,那么边上的花费就是(v-u间道路的长度)/ $t_i$。DAG上的最短路dp就能解。

代码如下:

 1 int n, m, a, b, p;
 2 int t[MAXN];
 3 int d[MAXM][MAXM];
 4 double dp[1 << 12][MAXM];
 5
 6 void solve() {
 7     for (int i = 0; i < 1 << n; i++) {
 8         fill(dp[i], dp[i] + m, INF);
 9     }
10     dp[(1 << n) - 1][a - 1] = 0;
11     double res = INF;
12     for (int S = (1 << n) - 1; S >= 0; S--) {
13         res = min(res, dp[S][b - 1]);
14         for (int v = 0; v < m; v++) {
15             for (int i = 0; i < n; i++) {
16                 if (S >> i & 1) {
17                     for (int u = 0; u < m; u++) {
18                         if (d[v][u] >= 0) {
19                             dp[S & ~(1 << i)][u] =
20                                 min(dp[S & ~(1 << i)][u],
21                                     dp[S][v] + (double)d[v][u] / t[i]);
22                         }
23                     }
24                 }
25             }
26         }
27     }
28     if (res == INF) {
29         printf("Impossible\n");
30     } else {
31         printf("%.3f\n", res);
32     }
33 }
34
35 int main() {
36 #ifndef ONLINE_JUDGE
37     freopen("input.txt", "r", stdin);
38 #endif  // !ONLINE_JUDGE
39     while (scanf("%d%d%d%d%d", &n, &m, &p, &a, &b) != EOF) {
40         if (p == 0 && m == 0 && n == 0 && a == 0 && b == 0) break;
41         MEM(t, 0), MEM(d, 0), MEM(dp, 0);
42         REP(i, 0, n - 1) scanf("%d", &t[i]);
43         REP(i, 0, MAXM - 1) REP(j, 0, MAXM - 1) d[i][j] = -1;
44         REP(i, 1, p) {
45             int u = READ(), v = READ(), w = READ();
46             u--, v--;
47             d[u][v] = d[v][u] = w;
48         }
49         solve();
50     }
51     return 0;
52 }

原文地址:https://www.cnblogs.com/romaLzhih/p/12315130.html

时间: 2024-10-03 14:56:39

DAG求最短路--TSP变形--状压dp的相关文章

POJ 3311 Hie with the Pie(TSP问题 状压DP)

Description The Pizazz Pizzeria prides itself in delivering pizzas to its customers as fast as possible. Unfortunately, due to cutbacks, they can afford to hire only one driver to do the deliveries. He will wait for 1 or more (up to 10) orders to be

JZYZOJ 1388 旅游 状压dp

http://172.20.6.3/Problem_Show.asp?id=1388 求拓扑排序方案数 状压dp,最开始以为是拓扑排序加数论或者搜索,没想到是状压dp,突然气死.jpg: 完全没有想到状态转移的方法,syq大佬太神了orz: 写的时候太沉迷与topsort对人顺序的分组类似于斯特林数求方案数(后来发现不是),忘了最原始的满足条件(事件a在事件b前完成)即可增加方案数的简单dp--(惭愧) 所以正解就是按dp进行顺序向状态里加人,对人实现排序,显然如果必须在a前的人都加到队列里了(

HDU 4568 Hunter 最短路+状压DP

题意:给一个n*m的格子,格子中有一些数,如果是正整数则为到此格子的花费,如果为-1表示此格子不可到,现在给k个宝藏的地点(k<=13),求一个人从边界外一点进入整个棋盘,然后拿走所有能拿走的宝藏的最小花费,如果一次不能拿走所有能拿到的或者根本拿不到任何宝藏,输出0. 解法:看到k的范围应该想到状态压缩,将每个格子都看成一个点,再新建两个点,一个表示边界外的起点,用0表示,一个表示边界外的终点,用n*m+1表示,然后相互建边,建有向边,边权为终点格子的花费值,(其实都不用建边,直接跑最短路也行)

【弱校胡策】2016.4.14 (bzoj2164)最短路+状压DP+矩阵乘法+高斯消元+树链剖分+线段树+背包DP

cyyz&qhyz&lwyz&gryz弱校胡策 命题人:cyyz ws_fqk T3暴力写挫了 50+10+0滚粗辣! 奇妙的约会(appointment.cpp/c/pas) [问题描述] DQS和sxb在网上结识后成为了非常好的朋友,并且都有着惊人 的OI水平.在NOI2333的比赛中,两人均拿到了金牌,并保送进入 HU/PKU.于是两人决定在这喜大普奔的时刻进行面基. NOI2333参赛选手众多,所以安排了n个考点,DQS在1号考点, 而sxb在n号考点.由于是举办全国性赛事

YYHS-蜀传之单刀赴会(梦回三国系列T2)(最短路+状压dp)

题目描述 [题目背景] 公元215年,刘备取益州,孙权令诸葛瑾找刘备索要荆州.刘备不答应,孙权极为恼恨,便派吕蒙率军取长沙.零陵.桂阳三郡.长沙.桂阳蜀将当即投降.刘备得知后,亲自从成都赶到公安(今湖北公安),派大将关羽争夺三郡.孙权也随即进驻陆口,派鲁肃屯兵益阳,抵挡关羽.双方剑拔弩张,孙刘联盟面临破裂,在这紧要关头,鲁肃为了维护孙刘联盟,不给曹操可乘之机,决定当面和关羽商谈."肃邀羽相见,各驻兵马百步上,但诸将军单刀俱会".双方经过会谈,缓和了紧张局势.随后,孙权与刘备商定平分荆州

【BZOJ1097】[POI2007]旅游景点atr 最短路+状压DP

[BZOJ1097][POI2007]旅游景点atr Description FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个城市登山,而是希望去另外什么地方喝下午茶.幸运的是,FGD的旅程不是既定的,他可以在某些旅行方案之间进行选择.由于FGD非常讨厌乘车的颠簸,他希望在满足他的要求的情况下,旅行的距离尽量短,这样他就有足够的精力来欣赏风景或者是泡MM了

HDU 4856 Tunnels (最短路+状压DP)

题意:给你N*N的网格,'.'表示可以走,'#'表示不能走,m条管道,每条管道有起点和终点坐标, Bob每次可以走到相邻的网格花费1s,问Bob走完m条管道要花多少时间:Bob在管道内不计算时间 即计算Bob从管道 i 的出口走到管道 j 的入口的时间Dis(e[i],s[j])的最小和,起点可以任意: 思路:看了题解说是状态压缩DP然后深入理解了下. 首先算出d[e[i]][s[j]]的最短距离,不能到达为-1: dp[i][j] : 表示以 j 为起点状态为 i 的最小值.其中 i 是用十进

HDU 5067 Harry And Dig Machine(状压DP)(TSP问题)

题目地址:pid=5067">HDU 5067 经典的TSP旅行商问题模型. 状压DP. 先分别预处理出来每两个石子堆的距离.然后将题目转化成10个城市每一个城市至少经过一次的最短时间模型.然后简单的状压DP就可以. 代码例如以下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #incl

BZOJ 1097: [POI2007]旅游景点atr( 最短路 + 状压dp )

先最短路预处理, 然后状压就行了 -------------------------------------------------------------------------- #include<cstdio> #include<cstring> #include<algorithm> #include<cctype> #include<queue> using namespace std; #define b(i) (1 <<