zoukankan      html  css  js  c++  java
  • 1254

    1254 - Prison Break
    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:
    ",++__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
    ");
     64                         else
     65                         {
     66                                 printf("%d
    ",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 }
    油!油!you@
  • 相关阅读:
    算法总结之 两个链表生成相加链表
    算法总结之 复制含有随机指针节点的链表
    算法总结之 将单向链表按某值划分成左边小、中间相等、右边大的形式
    在PHP5.3以上版本运行ecshop和ecmall出现的问题及解决方案
    windows下配置nginx+php环境
    ecmall程序结构图与数据库表分析
    ecmall数据字典
    Ecmall二次开发-增删改查操作
    PHP7:10件事情你需要知道的
    PHP命名空间规则解析及高级功能3
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5720712.html
Copyright © 2011-2022 走看看