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. BZOJ 3878: [Ahoi2014]奇怪的计算器

    BZOJ 3878: [Ahoi2014]奇怪的计算器 标签(空格分隔): OI-BZOJ OI-线段树 Time Limit: 10 Sec Memory Limit: 256 MB Descrip ...

  2. 跟我一起从零开始学WCF系列课程

    http://www.microsoft.com/china/msdn/events/webcasts/shared/webcast/Series/WCF_Begin.aspx 服务和协定 服务协定使 ...

  3. .NET利用RFC连接SAP,查询、读取SAP数据

    为黄朴整理!!!!!!!!!!!!!!!!! 在NuGet 添加 sapnco 一个简单的SAPCommand,方法 GetDataTableFromRFCTable 复制于 https://www. ...

  4. iOS 闭包传值 和 代理传值

    let vc = ViewController() let navc = UINavigationController(rootViewController: vc) window = UIWindo ...

  5. javascript的基本类型和引用类型

    一.基本类型和引用类型 基本的数据类型有5个:undefined,boolean,number,string,null ? 1 2 3 4 5 typeof null; //"object& ...

  6. IDEA整合Mybatis+Struts2+Spring(一)--新建项目

    1.IDEA新建Maven项目: (1)依次点击File->New->Project,弹出如下对话框: (2)在弹出的New Project页面上,①选择Maven,② 勾选Create ...

  7. Fakeapp 入门教程(2):使用篇!

    Fakeapp软件的使用主要分成了三个步骤, 使用之前请确保你的电脑配置还可以,推荐配置是:一张显存大于4G的N卡.Fakeapp是有支持CPU选项,但是用CPU跑非常慢. 获取脸部图片 训练模型 生 ...

  8. beautifulsoup解析

    beautifulsoup解析 python独有 优势:简单.便捷.高效 - 环境安装 需要将pip源设置为国内源 -需要安装:pip install bs4 bs4在使用时需要一个第三方库 pip ...

  9. P3387 【模板】缩点

    题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...

  10. Redis实现之字典

    字典 字典,又称为符号表(symbol table).关联数组(associative array)或映射(map),是一种用于保存键值对(key-value pair)的抽象数据结构.在字典中,一个 ...