1254 - Prison Break

  PDF (English) Statistics Forum
Time Limit: 2 second(s) Memory Limit: 32 MB

Michael Scofield has just broken out of the prison. Now he wants to go to a certain city for his next unfinished job. As you are the only programmer on his gang, he asked your help. As you know that the fuel prices vary in the cities, you have to write a code to help Scofield that instructs him where to take the fuel and which path to choose. Assume that his car uses one unit of fuel in one unit of distance. Now he gives you the starting city s where he starts his journey with his car, the destination city t and the capacity of the fuel tank of his car c, the code should find the route that uses the cheapest fuel cost. You can assume that Scofield‘s car starts with an empty fuel tank.

Input

Input starts with an integer T (≤ 5), denoting the number of test cases.

Each case starts with a line containing two integers n (2 ≤ n ≤ 100) and m (0 ≤ m ≤ 1000) where n denotes the number of cities and m denotes the number of roads. The next line contains n space separated integers, each lies between 1 and 100. The ith integer in this line denotes the fuel price (per unit) in the ith city. Each of the next m lines contains three integers u v w (0 ≤ u, v < n, 1 ≤ w ≤ 100, u ≠ v) denoting that there is a road between city u and v whose length is w.

The next line contains an integer q (1 ≤ q ≤ 100) denoting the number of queries by Scofield. Each of the next q lines contains the request. Each request contains three integers: c s t (1 ≤ c ≤ 100, 0 ≤ s, t < n) where c denotes the capacity of the tank, s denotes the starting city and t denotes the destination city.

Output

For each case, print the case number first. Then for each query print the cheapest trip from s to t using the car with the given capacity c or ‘impossible‘ if there is no way of getting from s to t with the given car.

Sample Input

Output for Sample Input


1

5 5

10 10 20 12 13

0 1 9

0 2 8

1 2 1

1 3 11

2 3 7

2

10 0 3

20 1 4


Case 1:

170

impossible

思路:最短路+贪心+dp;

dp[i][j]表示到第i个城市,油箱中还剩j油的最小费用;

Dijkstra来维护,
开始超时了,后来网上看了人家的思路;我开始每到一个点就将所有的状态枚举了出来,这样会导致枚举对答案没有贡献的。

所以我们按贪心策略来枚举,因为,Dijkstra(Elog(n))的算法取出来的点是当前花费最小的情况,

所以如果这个点可以到达下一个点不加油就到更新下一个点,然后如果当前的油量没超过油箱的容量就+1,加入队列,就和广搜差不多的思想,然后,如果到达了目标点,那么这个一定是最小的就跳出,因这个是当前最小的。

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <map>
  8 #include <queue>
  9 #include <vector>
 10 using namespace std;
 11 typedef  long long LL;
 12 typedef struct pp
 13 {
 14         int to;
 15         int id;
 16         int cost;
 17         bool operator<(const pp&cx)const
 18         {
 19                 return cost>cx.cost;
 20         }
 21 } ss;
 22 vector<ss>vec[200];
 23 int dp[200][200];
 24 bool flag[200][200];
 25 priority_queue<ss>que;
 26 int  dj(int n,int m,int c);
 27 int co[200];
 28 int main(void)
 29 {
 30         int i,j,k;
 31         scanf("%d",&k);
 32         int __ca=0;
 33         while(k--)
 34         {
 35                 int n,m;
 36                 scanf("%d %d",&n,&m);
 37                 for(i=0; i<200; i++)
 38                         vec[i].clear();
 39                 for(i=0; i<n; i++)
 40                 {
 41                         scanf("%d",&co[i]);
 42                 }
 43                 while(m--)
 44                 {
 45                         int x,y,co;
 46                         scanf("%d %d %d",&x,&y,&co);
 47                         ss ans;
 48                         ans.to=y;
 49                         ans.cost=co;
 50                         vec[x].push_back(ans);
 51                         ans.to=x;
 52                         vec[y].push_back(ans);
 53                 }
 54                 int t;
 55                 printf("Case %d:\n",++__ca);
 56                 scanf("%d",&t);
 57                 while(t--)
 58                 {
 59                         int c,u,v;
 60                         scanf("%d %d %d",&c,&u,&v);
 61                         int ask=dj(u,v,c);
 62                         if(ask==1e9)
 63                                 printf("impossible\n");
 64                         else
 65                         {
 66                                 printf("%d\n",ask);
 67                         }
 68                 }
 69         }
 70         return 0;
 71 }
 72 int  dj(int n,int m,int c)
 73 {
 74         int i,j,k;
 75         memset(flag,0,sizeof(flag));
 76         while(!que.empty())
 77         {
 78                 que.pop();
 79         }
 80         for(i=0; i<200; i++)
 81         {
 82                 for(j=0; j<200; j++)
 83                 {
 84                         dp[i][j]=1e9;
 85                 }
 86         }
 87         ss ans;
 88         ans.to=n;
 89         ans.cost=0;
 90         dp[n][0]=0;
 91         ans.id=0;
 92         que.push(ans);
 93         while(!que.empty())
 94         {
 95                 ss ak;
 96                 ak=que.top();
 97                 if(ak.to==m)
 98                    return ak.cost;
 99                 que.pop();
100                 if(dp[ak.to][ak.id]<ak.cost||flag[ak.to][ak.id])
101                 {
102                         continue;
103                 }
104                 else
105                 {
106                         flag[ak.to][ak.id]=true;
107                         for(i=0; i<vec[ak.to].size(); i++)
108                         {
109                                 ss aa=vec[ak.to][i];
110                                 {
111                                         if(ak.id>=aa.cost)
112                                         {  ss dd;
113                                                 if(dp[aa.to][ak.id-aa.cost]>ak.cost)
114                                                 {
115                                                         dp[aa.to][ak.id-aa.cost]=ak.cost;
116
117                                                         dd.to=aa.to;
118                                                         dd.id=ak.id-aa.cost;
119                                                         dd.cost=dp[aa.to][dd.id];
120                                                         que.push(dd);
121                                                 }
122                                         }
123                                      if(ak.id<c)
124                                         {      ss ad;
125                                                 ad.id=1+ak.id;
126                                                 ad.to=ak.to;
127                                                 ad.cost=co[ak.to]+ak.cost;
128                                                 if(dp[ad.to][ad.id]>ad.cost)
129                                                 {dp[ad.to][ad.id]=ad.cost;que.push(ad);}
130                                         }
131                                 }
132                         }
133                 }
134         }
135         return 1e9;
136 }
时间: 2024-08-23 22:21:01

1254 - Prison Break的相关文章

HDU 3681 Prison Break(bfs+二分+状压DP)

Prison Break Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3778    Accepted Submission(s): 992 Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But on

hdu 3681 Prison Break(状态压缩+bfs)

Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one day, the king of Rompire was captured by human beings. His thinking circuit was changed by human and thus became a tyrant. All those who are against him

hdu 3681 Prison Break (状态压缩+bfs+最短路)

Prison Break Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3214    Accepted Submission(s): 829 Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But on

HDU3681 Prison Break(状压dp)

Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one day, the king of Rompire was captured by human beings. His thinking circuit was changed by human and thus became a tyrant. All those who are against him

hdu 3511 Prison Break

http://acm.hdu.edu.cn/showproblem.php?pid=3511 题意: 给出n个相离或包含的圆,问最里层的圆是第几层 竖着的扫描线与圆在最左侧相切时 1.线在圆的上方或下方无交点,则该圆在第1层 2.线在圆的上下方都有交点,且上下方的交点属于同一个圆C,则该圆在圆C的里面一层 3.线在圆的上下方都有交点,上方交于圆E,下方交于圆F,EF其中一个在另一个里面,则该圆与在里面的那个圆处在同一层 4.线在圆的上下方都有交点,上方交于圆E,下方交于圆F,EF在同一层,则该圆

HDU3681(Prison Break)

题目链接:传送门 题目大意:给你一副n*m大小的图,'D'表示墙,'F'表示起点,'S'表示空地,'G'表示能源站,'Y'表示开关,一开始机器人处在'F'并有一个初始能量,每走一步会消耗一格能量 机器人需要在能量耗尽前经过所有'Y'至少一次,其中经过'G'可补满能量回初始值但每个'G'只能补一次,问至少需要几个能量才能达到要求. 题目思路:这个题感觉真的是很考验功底,集bfs,状态压缩DP,二分于一身,且实现细节不能马虎,实在是一道好题. 为什么说是状态压缩DP,You can assume t

HDU 3681 Prison Break floyd+状压+二分

题目链接:点击打开链接 题意: 给定n*m的矩阵: F:起点(有且仅有一个) D:坏点(不能走到这个点) G:能量池(走到这个点可以选择使用这个点的能量池,把电池充满,也可以暂时不用,只能使用一次) Y:目标点 问: 遍历所有Y点需要最小的电池容量是多少. 开始电池满电,每走一步消耗一格电. Y+G的个数<=15. n,m<=15 思路:状压YG,前面几位表示Y,后面几位表示G. 先跑个floyd,然后二分电池容量,状压dp判可行 #include <cstdio> #includ

【状压+二分+BFS】HDU 3681 Prison Break

通道:http://acm.hdu.edu.cn/showproblem.php?pid=3681 题意:机器人从F出发,走到G可以充电,D不能走进,走到Y关掉开关,要求把所有开关关掉,且电量最少,并求出初始最小电量. 思路:二分初始的电量,预处理任意G,Y,F之间的最短距离,然后状压dp[s][u]:状态为s的u为起点遍历整个图的最小布数. 代码:https://github.com/Mithril0rd/Rojo/blob/master/hdu3681.cpp TAG:代码来自华仔

HDU 3681 Prison Break

/* 给一个n*m的图,F代表起点,G代表充电池,一个充电池只能用一次,但可以用多个充电池,只能把电池充到最大(原始的电量),可以走过不用,D不能走, 问的是把所有的Y走一遍的原始的电量是多少 dp+状态压缩+二分+bfs dp[i][j]表示的状态是在i状态到达j的最大的电量 */ #include<stdio.h> #include<string.h> #include<queue> #define Max(a,b) a>b?a:b #define Min(a