Traveling by Stagecoach
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 3407   Accepted: 1322   Special Judge

Description

Once upon a time, there was a traveler.

He plans to travel using stagecoaches (horse wagons). His starting point and destination are fixed, but he cannot determine his route. Your job in this problem is to write a program which determines the route for him.

There are several cities in the country, and a road network connecting them. If there is a road between two cities, one can travel by a stagecoach from one of them to the other. A coach ticket is needed for a coach ride. The number of horses is specified in each of the tickets. Of course, with more horses, the coach runs faster.

At the starting point, the traveler has a number of coach tickets. By considering these tickets and the information on the road network, you should find the best possible route that takes him to the destination in the shortest time. The usage of coach tickets should be taken into account.

The following conditions are assumed.

  • A coach ride takes the traveler from one city to another directly connected by a road. In other words, on each arrival to a city, he must change the coach.
  • Only one ticket can be used for a coach ride between two cities directly connected by a road.
  • Each ticket can be used only once.
  • The time needed for a coach ride is the distance between two cities divided by the number of horses.
  • The time needed for the coach change should be ignored.

Input

The input consists of multiple datasets, each in the following format. The last dataset is followed by a line containing five zeros (separated by a space).

n m p a b 
t1 t2 ... tn 
x1 y1 z1 
x2 y2 z2 
... 
xp yp zp

Every input item in a dataset is a non-negative integer. If a line contains two or more input items, they are separated by a space.

n is the number of coach tickets. You can assume that the number of tickets is between 1 and 8. m is the number of cities in the network. You can assume that the number of cities is between 2 and 30. p is the number of roads between cities, which may be zero.

a is the city index of the starting city. b is the city index of the destination city. a is not equal to b. You can assume that all city indices in a dataset (including the above two) are between 1 and m.

The second line of a dataset gives the details of coach tickets. ti is the number of horses specified in the i-th coach ticket (1<=i<=n). You can assume that the number of horses is between 1 and 10.

The following p lines give the details of roads between cities. The i-th road connects two cities with city indices xi and yi, and has a distance zi (1<=i<=p). You can assume that the distance is between 1 and 100.

No two roads connect the same pair of cities. A road never connects a city with itself. Each road can be traveled in both directions.

Output

For each dataset in the input, one line should be output as specified below. An output line should not contain extra characters such as spaces.

If the traveler can reach the destination, the time needed for the best route (a route with the shortest time) should be printed. The answer should not have an error greater than 0.001. You may output any number of digits after the decimal point, provided that the above accuracy condition is satisfied.

If the traveler cannot reach the destination, the string "Impossible" should be printed. One cannot reach the destination either when there are no routes leading to the destination, or when the number of tickets is not sufficient. Note that the first letter of "Impossible" is in uppercase, while the other letters are in lowercase.

Sample Input

3 4 3 1 4
3 1 2
1 2 10
2 3 30
3 4 20
2 4 4 2 1
3 1
2 3 3
1 3 3
4 1 2
4 2 5
2 4 3 4 1
5 5
1 2 10
2 3 10
3 4 10
1 2 0 1 2
1
8 5 10 1 5
2 7 1 8 4 5 6 3
1 2 5
2 3 4
3 4 7
4 5 3
1 3 25
2 4 23
3 5 22
1 4 45
2 5 51
1 5 99
0 0 0 0 0

Sample Output

30.000
3.667
Impossible
Impossible
2.856

Hint

Since the number of digits after the decimal point is not specified, the above result is not the only solution. For example, the following result is also acceptable.

30.0

3.66667

Impossible

Impossible

2.85595

题目链接:POJ 2686

刷白书上的题目看到的,由于一条边只能走一次,在DAG的最短路中本来就是只走一次,那么只要再用一个状态表示走到某一个点用了哪些车票就好了。

用dis[v][S]表示走到v这个点,n张车票使用状态为S,显然一开始在点a,用了0张车票,因此初始状态为(a, 0),然后SPFA之后根据$[dis[b], dis[b] + (1 << n) - 1]$中的最小值判断即可,一开始边数写小了RE了几次……

代码:

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <sstream>
#include <numeric>
#include <cstring>
#include <bitset>
#include <string>
#include <deque>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 15;
const int MAX_V = 35;
const int MAX_E = MAX_V * MAX_V;
struct edge
{
int to, nxt;
double dx;
edge() {}
edge(int _to, int _nxt, double _dx): to(_to), nxt(_nxt), dx(_dx) {}
};
edge E[MAX_E << 1];
int head[MAX_V], tot;
double dis[MAX_V][1 << N];
int vis[MAX_V][1 << N];
double ti[N]; void init()
{
CLR(head, -1);
tot = 0;
}
void add(int s, int t, double dx)
{
E[tot] = edge(t, head[s], dx);
head[s] = tot++;
}
void spfa(int s, int n)
{
queue<pii>Q;
for (int i = 0; i < MAX_V; ++i)
fill(dis[i], dis[i] + (1 << N), 1e9);
CLR(vis, 0);
Q.push(pii(s, 0));
vis[s][0] = 1;
dis[s][0] = 0;
while (!Q.empty())
{
int u = Q.front().first;
int t = Q.front().second;
Q.pop();
vis[u][t] = 0;
for (int i = head[u]; ~i; i = E[i].nxt)
{
int v = E[i].to;
for (int j = 0; j < n; ++j)
{
if (t & (1 << j))
continue;
int V = (t | (1 << j));
double dx = E[i].dx / ti[j];
if (dis[v][V] > dis[u][t] + dx)
{
dis[v][V] = dis[u][t] + dx;
if (!vis[v][V])
{
vis[v][V] = 1;
Q.push(pii(v, V));
}
}
}
}
}
}
int main(void)
{
int n, m, p, a, b, i, x, y, z;
while (~scanf("%d%d%d%d%d", &n, &m, &p, &a, &b) && (n | m | p | a | b))
{
init();
for (i = 0; i < n; ++i)
{
scanf("%lf", &ti[i]);
}
for (i = 0; i < p; ++i)
{
scanf("%d%d%d", &x, &y, &z);
add(x, y, z * 1.0);
add(y, x, z * 1.0);
}
spfa(a, n);
double ans = *min_element(dis[b], dis[b] + (1 << n) + 1);
ans == 1e9 ? puts("Impossible") : printf("%.3f\n", ans);
}
return 0;
}

POJ 2686 Traveling by Stagecoach(状压二维SPFA)的更多相关文章

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

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

  2. POJ 2686 Traveling by Stagecoach 壮压DP

    大意是有一个人从某个城市要到另一个城市(点数<=30) 然后有n个马车票,相邻的两个城市走的话要消耗掉一个马车票. 花费的时间呢,是马车票上有个速率值,用边/速率就是花的时间. 问最后这个人花费 ...

  3. POJ 2686 Traveling by Stagecoach

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

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

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

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

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

  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. poj 2288 Islands and Bridges ——状压DP

    题目:http://poj.org/problem?id=2288 状压挺明显的: 一开始写了(记忆化)搜索,但一直T: #include<iostream> #include<cs ...

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

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

  9. POJ 3254 Corn Fields(状压DP)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13732   Accepted: 7216 Desc ...

随机推荐

  1. Python 之私有属性

    概要 在基类的定义中,如果有些属性或者方法,我们希望隐藏它,从而不被子类继承,或者使其不被实例直接访问到,这时候可以用到私有属性的命名方法.尽管类的所有属性和方法在某种意义上说都是"暴露的& ...

  2. 01HTML

    1.认识HTML标记 2.元信息标记meta 2.1设置页面关键字 2.2设置页面说明 2.3定义编辑工具 2.4添加作者信息 2.5设置网页文字及语言 2.6设置网页的定时跳转 <html&g ...

  3. Linux运维常用命令详解

    1.ls 文件属性:  -:普通文件  d:目录文件  b:块设备  c:字符设备文件  l:符号连接文件  p:命令管道  s:套接字文件  文件权限: 9位数字,每3位一组  文件硬链接次数  文 ...

  4. 问题:Could not install packages due to an EnvironmentError: [Errno 13] Permission denied:

    1.安装django 执行pip3 install --user django 2.解决方法:加--user   执行pip3 install --user django

  5. 二 python并发编程之多进程-理论

    一 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 举例(单核+多道,实现多个进程的并发执行): egon在一个时间段内有很多任务要做:python备课的任务,写书的任 ...

  6. DeepFaceLab报错, Could not create cudnn handle 解决方法!

    DeepFaceLab 虽然没有可视化界面,但是在众多换脸软件中,是安装最方便,更新最快,整体性能最佳的一个.这个软件对于系统依赖很低,也就是不需要装各种各样的“插件”. 但是即便如此,由于版本的不断 ...

  7. Python周末21天笔记

    模块一: 基础相互据类型之间的相互转换 1. 字符串str 与 列表 list 与字典 dict 以及 元祖tuple的转换 例一: 把字典的key和value的值取出来,按照顺序存入到list中 d ...

  8. Sql日期时间格式转换(转 子夜.)

    sql server2000中使用convert来取得datetime数据类型样式(全) 日期数据格式的处理,两个示例: CONVERT(varchar(16), 时间一, 20) 结果:2007-0 ...

  9. 可实现一键分享到多个平台(微信,微博,qq空间,人人等)

    友推是一款是面向移动应用的SDK分享组件,提供给开发者集成使用.通过友推,开发者可以轻松集成社会化分享功能,同时创建及管理推荐好友使用您应用的推荐奖励活动,用户推荐好友安装使用您的应用即可获得推荐奖励 ...

  10. 34、Java集合框架List,Map,Set等全面介绍(转载)

      Java Collections Framework是Java提供的对集合进行定义,操作,和管理的包含一组接口,类的体系结构.   Java集合框架的基本接口/类层次结构: java.util.C ...