大意是有一个人从某个城市要到另一个城市(点数<=30)

然后有n个马车票,相邻的两个城市走的话要消耗掉一个马车票。

花费的时间呢,是马车票上有个速率值,用边/速率就是花的时间。

问最后这个人花费的最短时间是多少

然后就是壮压DP了

dp[S][v] 代表当前消耗了S集合的车票走到v花费的最小时间

可以用spfa转移。

也可以直接转移。

直接转的原因是,这个图由于走路要消耗车票,所以实质上图是个DAG

看两种代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
#define MAXN 2222
#define INF 1000000007
using namespace std;
double dp[333][33];
typedef pair<int, int> P;
vector<P>g[33];
int t, n, m, src, des;
int num[33];
int main ()
{
int u, v, w;
while(scanf("%d%d%d%d%d", &t, &n, &m, &src, &des) != EOF)
{
if(!t && !n && !m && !src && !des) break;
for(int i = 0; i < t; i++) scanf("%d", &num[i]);
for(int i = 0; i <= n; i++) g[i].clear();
for(int i = 0; i < m; i++)
{
scanf("%d%d%d", &u, &v, &w);
g[u].push_back(make_pair(v, w));
g[v].push_back(make_pair(u, w));
}
for(int i = 0; i <= 300; i++)
for(int j = 0; j < 33; j++)
dp[i][j] = INF;
dp[0][src] = 0;
double res = INF;
for(int i = 0; i < (1 << t); i++)
{
for(u = 1; u <= n; u++)
for(int k = 0; k < t; k++)
if(!(i & (1 << k)))
{
for(int j = 0; j < g[u].size(); j++)
{
v = g[u][j].first;
w = g[u][j].second;
dp[i | (1 << k)][v] = min(dp[i | (1 << k)][v], dp[i][u] + (double)w / num[k]);
}
}
res = min(res, dp[i][des]);
}
if(res == INF) puts("Impossible");
else printf("%.3f\n", res); }
return 0;
}

然后是SPFA

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define MAXN 2222
#define INF 1000000007
using namespace std;
double dp[333][33];
typedef pair<int, int> P;
vector<P>g[33];
int t, n, m, src, des;
int num[33], vis[333][33];
queue<P>q;
void spfa()
{
for(int i = 0; i <= 300; i++)
for(int j = 0; j < 33; j++)
dp[i][j] = INF;
memset(vis, 0, sizeof(vis));
dp[0][src] = 0;
vis[0][src] = 1;
while(!q.empty()) q.pop();
q.push(make_pair(0, src));
while(!q.empty())
{
P top = q.front();
q.pop();
int S = top.first;
int u = top.second;
for(int j = 0; j < t; j++)
{
if(S & (1 << j)) continue;
for(int i = 0; i < g[u].size(); i++)
{
int v = g[u][i].first;
int w = g[u][i].second;
if(dp[S | (1 << j)][v] > dp[S][u] + (double)w / num[j])
{
dp[S | (1 << j)][v] = dp[S][u] + (double)w / num[j];
if(!vis[S | (1 << j)][v])
{
q.push(make_pair(S | (1 << j), v));
vis[S | (1 << j)][v] = 1;
}
}
}
}
}
double res = INF;
for(int i = 0; i < (1 << t); i++)
res = min(res, dp[i][des]);
if(res == INF) puts("Impossible");
else printf("%.3f\n", res);
}
int main ()
{
int u, v, w;
while(scanf("%d%d%d%d%d", &t, &n, &m, &src, &des) != EOF)
{
if(!t && !n && !m && !src && !des) break;
for(int i = 0; i < t; i++) scanf("%d", &num[i]);
for(int i = 0; i <= n; i++) g[i].clear();
for(int i = 0; i < m; i++)
{
scanf("%d%d%d", &u, &v, &w);
g[u].push_back(make_pair(v, w));
g[v].push_back(make_pair(u, w));
}
spfa();
}
return 0;
}

POJ 2686 Traveling by Stagecoach 壮压DP的更多相关文章

  1. POJ 2686 Traveling by Stagecoach (状压DP)

    题意:有一个人从某个城市要到另一个城市, 有n个马车票,相邻的两个城市走的话要消耗掉一个马车票.花费的时间呢,是马车票上有个速率值 ,问最后这个人花费的最短时间是多少. 析:和TSP问题差不多,dp[ ...

  2. poj 2686 Traveling by Stagecoach ---状态压缩DP

    题意:给出一个简单带权无向图和起止点,以及若干张马车车票,每张车票可以雇到相应数量的马. 点 u, v 间有边时,从 u 到 v 或从 v 到 u 必须用且仅用一张车票,花费的时间为 w(u, v) ...

  3. POJ 2686 Traveling by Stagecoach(状压二维SPFA)

    Traveling by Stagecoach Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 3407   Accepted ...

  4. POJ 2686 Traveling by Stagecoach

    状压DP dp[s][p]用了哪几张票,到哪个节点的最小费用. 注意:G++ %.3lf输出会WA,但C++能过:改成%.3f,C++,G++都能AC #include<cstdio> # ...

  5. POJ 2686 Traveling by Stagecoach(状压DP)

    [题目链接] http://poj.org/problem?id=2686 [题目大意] 给出一张无向图,你有n张马车票每张车票可以租用ti匹马, 用一张马车票从一个城市到另一个城市所用的时间为这两个 ...

  6. Traveling by Stagecoach /// 状压DP oj22914

    题目大意: 输入n,m,p,a,b n是车票数(1<=n<=8),m是城市数(2<=m<=30) p是路径数(可能为0),a是起点,b是终点 接下来一行有n个数 为每张车票的马 ...

  7. [Usaco2006 Nov]Corn Fields牧场的安排 壮压DP

    看到第一眼就发觉是壮压DP 然后就三进制枚举子集吧. 这题真是壮压入门好题... 对于dp[i][j] 表示第i行,j状态下前i行的分配方案数. 那么dp[i][j]肯定是从i-1行转过来的 那么由于 ...

  8. POJ 1185 炮兵阵地(状压DP)

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26426   Accepted: 10185 Descriptio ...

  9. POJ 2411 Mondriaan's Dream -- 状压DP

    题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...

随机推荐

  1. ubuntu 12.04 安装谷歌浏览器

    http://hi.baidu.com/kevin276/item/29bc1c96a208fabc82d29542 sudo dpkg -i google-chrome-stable_current ...

  2. linux 下 安装nexus

    1. 获得root权限  [ferrari@localhost ~]$ su -   2. 下载nexus集成版  [root@localhost ~]# cd /usr/local  [root@l ...

  3. 关于在页面上执行sql语句

    在页面上执行sql语句,首先在页面上顶一个文本域,让用户输入需要执行的sql语句. html代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML ...

  4. MUD江湖_MUD文字游戏_MUD五指_武林群侠_北侠_夺宝江湖_书剑_文字江湖游戏_MUD游戏下载

    MUD江湖_MUD文字游戏_MUD五指_武林群侠_北侠_夺宝江湖_书剑_文字江湖游戏_MUD游戏下载  武侠类手机文字游戏,经典再现高度自由玩法宠物 自制装备 师徒自立门派 自造武功欢迎来玩 Q群 1 ...

  5. python2.X和python3.X在同一平台下的切换技巧

    python2.X和python3.X在同一平台下的切换技巧 最近在自己的电脑上同时安装了python2.7.11和python3.5.1 在网上搜了一些答案,主要还是参照<learning p ...

  6. oc @property参数

  7. delphi 对TThread扩充TSimpleThread

    对线程的使用,是每个开发者都应该熟练掌握的,也是进阶的重要一环. 可以这样说,没有线程,连界面假死的问题都解决不了,就更别谈并行处理来提高效率了. 本例对线程进行改进,打造一个基础的线程,以后线程应用 ...

  8. SSH25个命令 + 深入SSH端口转发细节

    OpenSSH是SSH连接工具的免费版本.telnet,rlogin和ftp用户可能还没意识到他们在互联网上传输的密码是未加密的,但SSH是加密的,OpenSSH加密所有通信(包括密码),有效消除了窃 ...

  9. iOS5系统API和5个开源库的JSON解析速度测试

    iOS5系统API和5个开源库的JSON解析速度测试 iOS5新增了JSON解析的API,我们将其和其他五个开源的JSON解析库进行了解析速度的测试,下面是测试的结果和工程代码附件. 我们选择的测试对 ...

  10. Android TextView文字描边的实现!!

    Android开发:文字描边 转自:http://www.oschina.net/code/snippet_586849_37287 1. [代码][Java]代码 1 2 3 4 5 6 7 8 9 ...