• POJ-3635 Full Tank? (记忆化广搜)


    Description

    After going through the receipts from your car trip through Europe this summer, you realised that the gas prices varied between the cities you visited. Maybe you could have saved some money if you were a bit more clever about where you filled your fuel?

    To help other tourists (and save money yourself next time), you want to write a program for finding the cheapest way to travel between cities, filling your tank on the way. We assume that all cars use one unit of fuel per unit of distance, and start with an empty gas tank.

    Input

    The first line of input gives 1 ≤ n ≤ 1000 and 0 ≤ m ≤ 10000, the number of cities and roads. Then follows a line with n integers 1 ≤ pi ≤ 100, where pi is the fuel price in the ith city. Then follow m lines with three integers 0 ≤ u, v < n and 1 ≤ d ≤ 100, telling that there is a road between u and v with length d. Then comes a line with the number 1 ≤ q ≤ 100, giving the number of queries, and q lines with three integers 1 ≤ c ≤ 100, s and e, where c is the fuel capacity of the vehicle, s is the starting city, and e is the goal.

    Output

    For each query, output the price of the cheapest trip from s to e using a car with the given capacity, or "impossible" if there is no way of getting from s to e with the given car.

    Sample Input

    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

    Sample Output

    170
    impossible


    题目大意:n个城市,m条公路构成了一张n个顶点,m条无向边的图。现在要从一个城市驾车到另一个城市,每单位油能走1公里路,已知每个城市的油价(元/单位)和车的油箱容量,问到达目的地的最小花费是多少。
    题目分析:以当前的所在城市和油箱剩余油量作为状态参数,最多有 城市数x油箱容量=10^5 个状态,暴力是可以接受的,又让求最小花费,就敲定用广搜了。现在考虑状态转移,当到达一个城市时,无非面临了两种选择:1.当油量足够能通过下条路时,直接扩展;2.加一个单位油(加一个单位油没问题,如果加多的话,会重复,造成不必要的时间浪费)。问题看似已经解决,但如果仅仅是这样的话,会TLE。
      解决办法就是将广搜的过程记忆化,当达到某个状态时解比已经得到的解更优时,搜索才继续进行下去,并更新最优解。要开辟新的数组来记录状态的最优解。


    代码如下:
     1 # include<iostream>
     2 # include<cstdio>
     3 # include<queue>
     4 # include<cstring>
     5 # include<algorithm>
     6 using namespace std;
     7 const int INF=1<<30;
     8 struct node
     9 {
    10     int pos,tank,m;
    11     bool operator < (const node &a) const {
    12         return m>a.m;
    13     }
    14 };
    15 struct edge
    16 {
    17     int to,w,nxt;
    18 };
    19 edge e[20005];
    20 int n,vis[1005][105],dp[1005][105],head[1005],price[1005],cnt;
    21 void add(int u,int v,int w)
    22 {
    23     e[cnt].to=v;
    24     e[cnt].w=w;
    25     e[cnt].nxt=head[u];
    26     head[u]=cnt++;
    27 }
    28 void bfs(int v,int s,int t)
    29 {
    30     priority_queue<node>q;
    31     for(int i=0;i<=n;++i)
    32         for(int j=0;j<=v;++j)
    33             dp[i][j]=INF;
    34     memset(vis,0,sizeof(vis));
    35     dp[s][0]=0;
    36     node sta;
    37     sta.m=0,sta.pos=s,sta.tank=0;
    38     q.push(sta);
    39     while(!q.empty()){
    40         node u=q.top();
    41         q.pop();
    42         int pos=u.pos;
    43         vis[pos][u.tank]=1;
    44         if(pos==t){
    45             printf("%d
    ",u.m);
    46             return ;
    47         }
    48         for(int i=head[pos];i!=-1;i=e[i].nxt){
    49             if(u.tank>=e[i].w&&!vis[e[i].to][u.tank-e[i].w]&&dp[e[i].to][u.tank-e[i].w]>u.m){
    50                 dp[e[i].to][u.tank-e[i].w]=u.m;
    51                 node nxt;
    52                 nxt.pos=e[i].to,nxt.tank=u.tank-e[i].w,nxt.m=u.m;
    53                 q.push(nxt);
    54             }
    55         }
    56         if(u.tank+1<=v&&!vis[pos][u.tank+1]&&dp[pos][u.tank+1]>dp[pos][u.tank]+price[pos]){
    57             dp[pos][u.tank+1]=dp[pos][u.tank]+price[pos];
    58             node nxt;
    59             nxt.pos=pos,nxt.m=dp[pos][u.tank+1],nxt.tank=u.tank+1;
    60             q.push(nxt);
    61         }
    62     }
    63     printf("impossible
    ");
    64 }
    65 int main()
    66 {
    67     int m,q,a,b,c;
    68     while(scanf("%d%d",&n,&m)!=EOF)
    69     {
    70         cnt=0;
    71         for(int i=0;i<n;++i)
    72             scanf("%d",price+i);
    73         memset(head,-1,sizeof(head));
    74         while(m--){
    75             scanf("%d%d%d",&a,&b,&c);
    76             add(a,b,c);
    77             add(b,a,c);
    78         }
    79         scanf("%d",&q);
    80         while(q--){
    81             scanf("%d%d%d",&c,&a,&b);
    82             bfs(c,a,b);
    83         }
    84     }
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    Django 之Redis配置
    python之类中如何判断是函数还是方法
    Anaconda 虚拟环境安装及应用
    【转载】IDEA:XML配置提示URI is not registered
    idea中配置xml不自动提示解决方案
    Java接口成员变量和方法默认修饰符
    [转载]java中Date,SimpleDateFormat
    intellij idea 的全局搜索快捷键方法
    【转载】使用IntelliJ IDEA提示找不到struts-default文件
    【转载】Jmeter分布式部署测试-----远程连接多台电脑做压力性能测试
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/4726111.html
Copyright © 2020-2023  润新知