zoukankan      html  css  js  c++  java
  • poj 3635 Full Tank? ( bfs+dp思想 )

    Full Tank?
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 5857   Accepted: 1920

    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 ≤ uv < 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

    Source


    题意:

    给定n(n<=1000)个编号为0..n-1加油站的每单位油价格,再给定m(m<=10000)条边,并给出通过其所需油(<=100),询问q(q<=100)次,询问油箱容量为c(c<=100)时,s到e的所需最小费用。


    思路:

    dp[i][j]表示到达i点剩余油量为j时的最小花费,由于是在图上,没有确定的递推方向,那么用一个结构体{ u-当前位置、oil-剩余油量、cst-当前花费 },进行堆优化bfs就能解决问题了。

    到达一个状态后看做有两种操作:

    1.加一升油。

    2.到达下一个节点。

    那么所有的有效状态就能表示出来了,第一次到达e的费用即为最小花费。


    ps:这种做法和优先队列优化的最短路很像的,只是状态多了一维。


    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <string>
    #include <map>
    #include <stack>
    #include <vector>
    #include <set>
    #include <queue>
    #pragma comment (linker,"/STACK:102400000,102400000")
    #define maxn 1005
    #define MAXN 20005
    #define mod 1000000007
    #define INF 0x3f3f3f3f
    #define pi acos(-1.0)
    #define eps 0.000001
    using namespace std;
    
    int n,m,ans,cnt,cap,s,e;
    int cost[maxn],pp[maxn];
    bool vis[maxn][maxn];
    int dp[maxn][maxn];
    struct Node
    {
        int v,next,w;
    } edge[MAXN];
    struct node
    {
        int u,oil,cst;
        bool operator <(const node &xx)const
        {
            return cst>xx.cst;
        }
    } cur,now;
    priority_queue<node>q;
    
    void addedge(int u,int v,int w)
    {
        cnt++;
        edge[cnt].v=v;
        edge[cnt].w=w;
        edge[cnt].next=pp[u];
        pp[u]=cnt;
    }
    bool bfs()
    {
        int i,j,u,v,w,oil,cst;
        memset(dp,0x3f,sizeof(dp));
        memset(vis,0,sizeof(vis));
        while(!q.empty()) q.pop();
        cur.u=s;
        cur.oil=0;
        cur.cst=0;
        dp[s][0]=0;
        q.push(cur);
        while(!q.empty())
        {
            now=q.top();
            q.pop();
            u=now.u;
            oil=now.oil;
            cst=now.cst;
            if(u==e)
            {
                ans=cst;
                return true ;
            }
            if(vis[u][oil]) continue ;
            vis[u][oil]=1;
            if(oil<cap)
            {
                cur.u=now.u;
                cur.oil=oil+1;
                cur.cst=cst+cost[u];
                if(dp[cur.u][cur.oil]>cur.cst&&!vis[cur.u][cur.oil])
                {
                    dp[cur.u][cur.oil]=cur.cst;
                    q.push(cur);
                }
            }
            for(i=pp[u]; i; i=edge[i].next)
            {
                v=edge[i].v;
                w=edge[i].w;
                if(oil>=w&&dp[v][oil-w]>cst&&!vis[v][oil-w])
                {
                    dp[v][oil-w]=cst;
                    cur.u=v;
                    cur.oil=oil-w;
                    cur.cst=cst;
                    q.push(cur);
                }
            }
        }
        return false ;
    }
    int main()
    {
        int i,j,t,u,v,w,q;
        while(~scanf("%d%d",&n,&m))
        {
            for(i=0; i<n; i++)
            {
                scanf("%d",&cost[i]);
            }
            cnt=0;
            memset(pp,0,sizeof(pp));
            for(i=1; i<=m; i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);
                addedge(v,u,w);
            }
            scanf("%d",&q);
            for(i=1; i<=q; i++)
            {
                scanf("%d%d%d",&cap,&s,&e);
                if(bfs()) printf("%d
    ",ans);
                else printf("impossible
    ");
            }
        }
        return 0;
    }
    






  • 相关阅读:
    “XXXXX” is damaged and can’t be opened. You should move it to the Trash 解决方案
    深入浅出 eBPF 安全项目 Tracee
    Unity3d开发的知名大型游戏案例
    Unity 3D 拥有强大的编辑界面
    Unity 3D物理引擎详解
    Unity 3D图形用户界面及常用控件
    Unity 3D的视图与相应的基础操作方法
    Unity Technologies 公司开发的三维游戏制作引擎——Unity 3D
    重学计算机
    windows cmd用户操作,添加,设备管理员组,允许修改密码
  • 原文地址:https://www.cnblogs.com/pangblog/p/3367716.html
Copyright © 2011-2022 走看看